Ahoj,
netus(ím, jestli to standard JPA r(es(í ne(jak obecne(, ale pro
hibernate jsem musel provést následující ve(c. Je to pome(rne( c(astý problém
r(es(ený v ne(kolika diskusních threadech (link ted( dohromady nedám, protoz(e
bych ho musel znovu hledat).
Pr(ikládám zdrojáky mého modelu, kde jsou enumerace pouz(ity a r(es(ení
pro Hibernate ORM. Du*lez(ité jsou tr(ídy:
Enum tr(ídy: Gender a SkillLevel
Helper classy pro Hibernate:
EnumUserType<E extends Enum<E>>
GenderUserType extends EnumUserType<Gender>
SkillLevelUserType extends EnumUserType<SkillLevel>
které r(íkají Hibernate, jak se má k daným Enum hodnotám chovat pr(i
persistování a nac(ítání. Vlastní definice v HBM XML je potom napr(. pro
Goalkeepera, který pouz(ívá Enumy takováto:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
'-//Hibernate/Hibernate Mapping DTD 3.0//EN'
'http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd'>
<hibernate-mapping>
<class name="com.fgf.ot.model.Goalkeeper" table="GOALKEEPERS">
<id name="id" column="ID" type="java.lang.Long">
<generator class="native"/>
</id>
<property name="firstname"/>
<property name="surname"/>
<property name="age" type="java.lang.Integer"/>
<property name="gender" type="com.fgf.ot.model.GenderUserType"/>
<property name="catchSkill" type="com.fgf.ot.model.SkillLevelUserType"/>
<property name="perception" type="com.fgf.ot.model.SkillLevelUserType"/>
</class>
</hibernate-mapping>
Taky bych si to pr(edstavoval jednodus(s(í ;)
Novoj
--
--------------------------------------------------------------
Ing. Jan Novotný
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
http://blog.novoj.net
Mys(lenky dne otce Fura
--------------------------------------------------------------
Tomas Hubalek napsal(a):
Zdar,
mam takovy dotaz. Chtel bych udelat JPA mapping (Hibernate, ale to
snad neni podstatne) nasledujicich trid a nevim, jak to oannotovat.
public enum Group { A, B, C}
@Entity
public class Person {
...
@?????
Set<Group> groups;
...
}
Pokud chci jenom jednu property, tak jde pouzit @Enumerated(), ale pro
Set to nefunguje.
Mate nekdo nejaky tip? Nebo mam obetovat enum a udelat si UserType.
Tom
!DSPAM:144,45c1d9e5253311903020241!
/*
* TeamMember.java
*
* Created on 14. listopad 2006, 21:39
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package com.fgf.ot.model;
import com.fgf.ot.exception.ValidateException;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import java.io.Serializable;
/**
* Ancestor for every team member.
*
* @author Rodina Novotnych
*/
public abstract class TeamMember implements Serializable, Cloneable {
/**
* Serial uid.
*/
static final long serialVersionUID = 562771986777794141L;
/**
* Unique id.
*/
private Long id;
/**
* Firstname.
*/
private String firstname;
/**
* Surname.
*/
private String surname;
/**
* Age.
*/
private Integer age;
/**
* Gender.
*/
private Gender gender;
/**
* Getter.
*
* @return
*/
public Long getId() {
return id;
}
/**
* Setter.
*
* @param id
*/
public void setId(Long id) {
this.id = id;
}
/**
* Getter.
*
* @return
*/
public String getFirstname() {
return firstname;
}
/**
* Setter.
*
* @param firstname
*/
public void setFirstname(String firstname) {
this.firstname = firstname;
}
/**
* Getter.
*
* @return
*/
public String getSurname() {
return surname;
}
/**
* Setter.
*
* @param surname
*/
public void setSurname(String surname) {
this.surname = surname;
}
/**
* Getter.
*
* @return
*/
public Integer getAge() {
return age;
}
/**
* Setter.
*
* @param age
*/
public void setAge(Integer age) {
this.age = age;
}
/**
* Getter.
*
* @return
*/
public Gender getGender() {
return gender;
}
/**
* Setter.
*
* @param gender
*/
public void setGender(Gender gender) {
this.gender = gender;
}
/**
* Performs work, that member of this type should do.
*
* @return simple string representing object`s activity
*/
public abstract String work();
/**
* Validates objects itself whether it has initialized all mandatory
fields, and that fields contains valid
* values.
*
* @throws ValidateException when any error has been found
*/
public void validate() throws ValidateException {
if (id == null) {
throw new ValidateException("Id cannot be null!");
}
if ((age == null) || (age.intValue() <= 0)) {
throw new ValidateException("Age cannot be lower than
1!");
}
if (gender == null) {
throw new ValidateException("Gender cannot be null!");
}
if (firstname == null) {
throw new ValidateException("First name cannot be
null!");
}
if (surname == null) {
throw new ValidateException("Surname cannot be null!");
}
}
/**
* Makes copy of current object.
*
* @return copy
*
* @throws CloneNotSupportedException
*/
public Object clone() throws CloneNotSupportedException {
Object retValue;
retValue = super.clone();
TeamMember tm = (TeamMember)retValue;
tm.setId(null);
tm.setFirstname(firstname);
tm.setSurname(surname);
tm.setAge(age);
tm.setGender(gender);
return retValue;
}
/**
* HashCode .
*
* @return
*/
public int hashCode() {
return new
HashCodeBuilder().append(id).append(firstname).append(surname).append(age).append(gender).hashCode();
}
/**
* True if object is equal to this object.
*
* @param obj
*
* @return
*/
public boolean equals(Object obj) {
if (obj instanceof TeamMember == false) {
return false;
}
if (this == obj) {
return true;
}
TeamMember rhs = (TeamMember)obj;
return new EqualsBuilder().append(id, rhs.id).append(firstname,
rhs.firstname).append(surname, rhs.surname)
.append(age,
rhs.age).append(gender, rhs.gender).isEquals();
}
/**
* String representation of object.
*
* @return
*/
public String toString() {
return new
ToStringBuilder(this).append(id).append(firstname).append(surname).append(age).append(gender)
.toString();
}
}
/*
* Sportsman.java
*
* Created on 14. listopad 2006, 21:52
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package com.fgf.ot.model;
/**
* Poor sport worker.
*
* @author Rodina Novotnych
*/
public abstract class Sportsman extends TeamMember {
/**
* Serial UID.
*/
static final long serialVersionUID = 2305583800299205422L;
/**
* Performs work, that member of this type should do.
*
* @return simple string representing object`s activity
*/
public String work() {
return "Sportsman tries to make his best in competitions.";
}
}
/*
* SkillLevelUserType.java
*
* Created on 17. listopad 2006, 22:02
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package com.fgf.ot.model;
/**
* User type declaration for Hibernate.
*
* @author Rodina Novotnych
*/
public class SkillLevelUserType extends EnumUserType<SkillLevel> {
/**
* Constructor.
*/
public SkillLevelUserType() {
super(SkillLevel.class);
}
}
/*
* SkillLevel.java
*
* Created on 17. listopad 2006, 22:07
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package com.fgf.ot.model;
/**
* Represents skill level in various men abilities.
**/
public enum SkillLevel {
LOW,
AVERAGE,
INTERMEDIATE,
HIGH,
SUPREME;
}
;
/*
* ServiceMan.java
*
* Created on 14. listopad 2006, 21:52
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package com.fgf.ot.model;
/**
* ServiceMan.
*
* @author Rodina Novotnych
*/
public class ServiceMan extends TeamMember {
/**
* Serial UID.
*/
static final long serialVersionUID = 6808040193229777785L;
/**
* Performs work, that member of this type should do.
*
* @return simple string representing object`s activity
*/
public String work() {
return "Service man " + getFirstname() + " " + getSurname() + "
keeps an eye on things.";
}
}
/*
* GoalKeeper.java
*
* Created on 14. listopad 2006, 22:21
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package com.fgf.ot.model;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
/**
* GoalKeeper.
*
* @author Rodina Novotnych
*/
public class Goalkeeper extends Sportsman {
/**
* Serial UID.
*/
static final long serialVersionUID = 2984813986540511772L;
/**
* Represens ability to block shots on gate.
*/
private SkillLevel catchSkill;
/**
* Represents ability to react quickly.
*/
private SkillLevel perception;
/**
* Getter.
*
* @return
*/
public SkillLevel getCatchSkill() {
return catchSkill;
}
/**
* Setter.
*
* @param catchSkill
*/
public void setCatchSkill(SkillLevel catchSkill) {
this.catchSkill = catchSkill;
}
/**
* Getter.
*
* @return
*/
public SkillLevel getPerception() {
return perception;
}
/**
* Setter.
*
* @param perception
*/
public void setPerception(SkillLevel perception) {
this.perception = perception;
}
/**
* Performs work, that member of this type should do.
*
* @return simple string representing object`s activity
*/
public String work() {
return super.work() + "Goalkeeper " + getFirstname() + " " +
getSurname() + " with " + perception
+ " perception and " + catchSkill + " catch skill
blocks shots on his gate.";
}
/**
* Makes copy of current object.
*
* @return copy
*
* @throws CloneNotSupportedException
*/
public Object clone() throws CloneNotSupportedException {
Object retValue;
retValue = super.clone();
Goalkeeper tm = (Goalkeeper)retValue;
tm.setCatchSkill(catchSkill);
tm.setPerception(perception);
return retValue;
}
/**
* HashCode.
*
* @return
*/
public int hashCode() {
return new
HashCodeBuilder().appendSuper(super.hashCode()).append(catchSkill).append(perception).toHashCode();
}
/**
* True if object is equal to this object.
*
* @param obj
*
* @return
*/
public boolean equals(Object obj) {
if (obj instanceof Goalkeeper == false) {
return false;
}
if (this == obj) {
return true;
}
Goalkeeper rhs = (Goalkeeper)obj;
return new
EqualsBuilder().appendSuper(super.equals(rhs)).append(catchSkill,
rhs.catchSkill)
.append(perception, rhs.perception).isEquals();
}
/**
* String representation of object.
*
* @return
*/
public String toString() {
return new
ToStringBuilder(this).appendSuper(super.toString()).append(catchSkill).append(perception).toString();
}
}
/*
* GenderUserType.java
*
* Created on 17. listopad 2006, 22:02
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package com.fgf.ot.model;
/**
* User type declaration for Hibernate.
*
* @author Rodina Novotnych
*/
public class GenderUserType extends EnumUserType<Gender> {
/**
* Constructor.
*/
public GenderUserType() {
super(Gender.class);
}
}
/*
* Gender.java
*
* Created on 17. listopad 2006, 22:06
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package com.fgf.ot.model;
public enum Gender {
MALE,
FEMALE;
}
;
/*
* EnumUserType.java
*
* Created on 17. listopad 2006, 22:05
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package com.fgf.ot.model;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
/**
* Hibernate user type translator. Allows to persist & load enum types into /
from storage.
*
* @see org.hibernate.usertype.UserType
* @param <E> enum class to be encapsulated.
*/
public abstract class EnumUserType<E extends Enum<E>> implements UserType {
/**
* Enum class to be encapsulated.
*/
private Class<E> clazz = null;
/**
* Constructor.
*
* @param c
*/
protected EnumUserType(Class<E> c) {
this.clazz = c;
}
/**
* Contains information about how to store enum type.
*/
private static final int[] SQL_TYPES = { Types.VARCHAR };
/**
* Returns information about how to store enum type.
*
* @return
*/
public int[] sqlTypes() {
return SQL_TYPES;
}
/**
* Returns class to be returned in connection with stored value.
*
* @return
*/
public Class returnedClass() {
return clazz;
}
/**
* Returns value from result set.
*
* @param resultSet
* @param names
* @param owner
*
* @return
*
* @throws HibernateException
* @throws SQLException
*/
public Object nullSafeGet(ResultSet resultSet, String[] names, Object
owner)
throws HibernateException,
SQLException {
String name = resultSet.getString(names[0]);
E result = null;
if (!resultSet.wasNull()) {
result = Enum.valueOf(clazz, name);
}
return result;
}
/**
* Returns value from prepared statement.
*
* @param preparedStatement
* @param value
* @param index
*
* @throws HibernateException
* @throws SQLException
*/
public void nullSafeSet(PreparedStatement preparedStatement, Object
value, int index)
throws HibernateException,
SQLException {
if (null == value) {
preparedStatement.setNull(index, Types.VARCHAR);
} else {
preparedStatement.setString(index,
((Enum)value).name());
}
}
/**
* Deep copies value on input.
*
* @param value
*
* @return
*
* @throws HibernateException
*/
public Object deepCopy(Object value) throws HibernateException {
return value;
}
/**
* Returns mutability flag.
*
* @return
*/
public boolean isMutable() {
return false;
}
/**
* Converts seralizable into object.
*
* @param cached
* @param owner
*
* @return
*
* @throws HibernateException
*/
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached;
}
/**
* Converts object into serializable.
*
* @param value
*
* @return
*
* @throws HibernateException
*/
public Serializable disassemble(Object value)
throws
HibernateException {
return (Serializable)value;
}
/**
* Replaces one object with another.
*
* @param original
* @param target
* @param owner
*
* @return
*
* @throws HibernateException
*/
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
return original;
}
/**
* HashCode.
*
* @param x
*
* @return
*
* @throws HibernateException
*/
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
/**
* Equals.
*
* @param x
* @param y
*
* @return
*
* @throws HibernateException
*/
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y) {
return true;
}
if ((null == x) || (null == y)) {
return false;
}
return x.equals(y);
}
}
/*
* Defender.java
*
* Created on 14. listopad 2006, 22:21
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package com.fgf.ot.model;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
/**
* Defender.
*
* @author Rodina Novotnych
*/
public class Defender extends Sportsman {
/**
* Serial UID.
*/
static final long serialVersionUID = 7335172232309760390L;
/**
* Represents ability to protect the gate.
*/
private SkillLevel defendSkill;
/**
* Represents speed of the member. The faster member is, the more
success he has when defending the gate.
*/
private SkillLevel speed;
/**
* Getter.
*
* @return
*/
public SkillLevel getDefendSkill() {
return defendSkill;
}
/**
* Setter.
*
* @param defendSkill
*/
public void setDefendSkill(SkillLevel defendSkill) {
this.defendSkill = defendSkill;
}
/**
* Getter.
*
* @return
*/
public SkillLevel getSpeed() {
return speed;
}
/**
* Setter.
*
* @param speed
*/
public void setSpeed(SkillLevel speed) {
this.speed = speed;
}
/**
* Performs work, that member of this type should do.
*
* @return simple string representing object`s activity
*/
public String work() {
return super.work() + "Defender " + getFirstname() + " " +
getSurname() + " with " + speed + " speed and "
+ defendSkill + " defend skill blocks oponent`s
attacks.";
}
/**
* Makes copy of current object.
*
* @return copy
*
* @throws CloneNotSupportedException
*/
public Object clone() throws CloneNotSupportedException {
Object retValue;
retValue = super.clone();
Defender tm = (Defender)retValue;
tm.setDefendSkill(defendSkill);
tm.setSpeed(speed);
return retValue;
}
/**
* HashCode.
*
* @return
*/
public int hashCode() {
return new
HashCodeBuilder().appendSuper(super.hashCode()).append(defendSkill).append(speed).toHashCode();
}
/**
* True if object is equal to this object.
*
* @param obj
*
* @return
*/
public boolean equals(Object obj) {
if (obj instanceof Defender == false) {
return false;
}
if (this == obj) {
return true;
}
Defender rhs = (Defender)obj;
return new
EqualsBuilder().appendSuper(super.equals(rhs)).append(defendSkill,
rhs.defendSkill)
.append(speed, rhs.speed).isEquals();
}
/**
* String representation of object.
*
* @return
*/
public String toString() {
return new
ToStringBuilder(this).appendSuper(super.toString()).append(defendSkill).append(speed).toString();
}
}
/*
* Coach.java
*
* Created on 14. listopad 2006, 21:52
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package com.fgf.ot.model;
/**
* Leader and trainer of sportsmen.
*
* @author Rodina Novotnych
*/
public class Coach extends TeamMember {
/**
* Serial UID.
*/
static final long serialVersionUID = 1942739182786754410L;
/**
* Performs work, that member of this type should do.
*
* @return simple string representing object`s activity
*/
public String work() {
return "Coach " + getFirstname() + " " + getSurname() + "
trains his team.";
}
}
/*
* Attacker.java
*
* Created on 14. listopad 2006, 22:21
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package com.fgf.ot.model;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
/**
* Attacker.
*
* @author Rodina Novotnych
*/
public class Attacker extends Sportsman {
/**
* Serial UID.
*/
static final long serialVersionUID = -7740943376702138147L;
/**
* Represents ability to score on oponent`s gate.
*/
private SkillLevel attackSkill;
/**
* Represents speed of the member. The faster member is, the more
success he has when attacking the gate.
*/
private SkillLevel speed;
/**
* Getter.
*
* @return
*/
public SkillLevel getAttackSkill() {
return attackSkill;
}
/**
* Setter.
*
* @param attackSkill
*/
public void setAttackSkill(SkillLevel attackSkill) {
this.attackSkill = attackSkill;
}
/**
* Getter.
*
* @return
*/
public SkillLevel getSpeed() {
return speed;
}
/**
* Setter.
*
* @param speed
*/
public void setSpeed(SkillLevel speed) {
this.speed = speed;
}
/**
* Performs work, that member of this type should do.
*
* @return simple string representing object`s activity
*/
public String work() {
return super.work() + " Attacker " + getFirstname() + " " +
getSurname() + " with " + speed + " speed and "
+ attackSkill + " attack skill tries to score on
oponent`s gate.";
}
/**
* Makes copy of current object.
*
* @return copy
*
* @throws CloneNotSupportedException
*/
public Object clone() throws CloneNotSupportedException {
Object retValue;
retValue = super.clone();
Attacker tm = (Attacker)retValue;
tm.setAttackSkill(attackSkill);
tm.setSpeed(speed);
return retValue;
}
/**
* HashCode.
*
* @return
*/
public int hashCode() {
return new
HashCodeBuilder().appendSuper(super.hashCode()).append(attackSkill).append(speed).toHashCode();
}
/**
* True if object is equal to this object.
*
* @param obj
*
* @return
*/
public boolean equals(Object obj) {
if (obj instanceof Attacker == false) {
return false;
}
if (this == obj) {
return true;
}
Attacker rhs = (Attacker)obj;
return new
EqualsBuilder().appendSuper(super.equals(rhs)).append(attackSkill,
rhs.attackSkill)
.append(speed, rhs.speed).isEquals();
}
/**
* String representation of object.
*
* @return
*/
public String toString() {
return new
ToStringBuilder(this).appendSuper(super.toString()).append(attackSkill).append(speed).toString();
}
}