Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
session.createCriteria(Person.class).add(Restrictions.eq("status", Status.NEW)
session.createCriteria(Person.class).createAlias("status", "st").add(Restrictions.eq("status_id", "id")).add(Restrictions.eq("st.id", "NEW")
Status.NEW.ordinal()
писать совсем не обязательно, можно просто Status.NEW
— Hibernate (и JPA в целом) отлично это переваривает, причём внутри оно использует не метод ordinal()
, а getEnumConstants()
— это внезапно выяснилось в ходе отладки, после чего была добавлена замена массива $VALUES
.getEnumConstants()
, так и valueOf()
и всего остального их функционала. Чем и удобен — no side effects at all.Restrictions.eq()
в варианте с JOIN'ом конечно же st.code
, а не st.id
:session.createCriteria(Person.class).createAlias("status", "st").add(Restrictions.eq("status_id", "id")).add(Restrictions.eq("st.code", "NEW")
public enum CustomerStatusType implements MyEnum {
ACTIVE("ACT", "Active"),
DELETED("DEL", "Deleted"),
SUSPENDED("SUS", "Suspended");
private String id;
private String description;
private CustomerStatusType(String id, String description) {
this.id = id;
this.description = description;
}
@Override public String getId() {return this.id;}
@Override public String getDescription() {return this.description;}
public static CustomerStatusType getInstanceById(String id) {...}
}
@Entity
public class Customer {
@Type(type = "example.EnumerationIdMapper",
parameters = { @Parameter(name = "classname", value = "example.CustomerStatusType") })
@Column(name = "status", nullable = false)
private CustomerStatusType status;
@Type(type = "example.EnumerationIdListMapper",
parameters = { @Parameter(name = "classname", value = "example.CustomerStatusType") })
@Column(name = "statuses", nullable = true)
private List<CustomerStatusType> statuses;
}
/**
* пример
*/
public class EnumerationIdMapper implements UserType, ParameterizedType
...
protected Class myEnum = null;
protected Method getInstanceById =null;
/**
* @see org.hibernate.usertype.UserType#nullSafeGet(ResultSet, java.lang.String[],
* java.lang.Object)
*/
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner)
throws HibernateException, SQLException {
MyEnum targetObject = null;
try {
String id = resultSet.getString(names[0]);
if (!resultSet.wasNull()) {
targetObject = (MyEnum) this.getInstanceById.invoke(
myEnum, new Object[] { id.trim() });
}
catch (Exception e) {
// do something...
}
return targetObject;
}
/**
* @see org.hibernate.usertype.UserType#nullSafeSet(PreparedStatement, java.lang.Object, int)
*/
public void nullSafeSet(PreparedStatement statement, Object value, int index)
throws HibernateException, SQLException {
if (value == null) {
statement.setNull(index, Types.VARCHAR);
} else {
statement.setString(index, ((MyEnum) value).getId());
}
}
/**
* @see org.hibernate.usertype.ParameterizedType#setParameterValues(java.util.Properties)
*/
public void setParameterValues(Properties properties) {
if (properties == null) {
return;
}
String className = properties.getProperty("classname");
if (className == null || className.length() == 0) {
return;
}
try {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class<?> clazz = cl.loadClass(className);
this.myEnum = (Class<T>) clazz.asSubclass(Enum.class);
this.getInstanceById = myEnum.getMethod("getInstanceById",
new Class[] { String.class });
} catch (ClassNotFoundException cnfe) {
throw new HibernateException("class not found", cnfe);
}
}
...
}
Query query = em.createQuery("select c from Customer c where c.status:=statusValue");
query.setParameter("statusValue", CustomerStatusType.ACTIVE);
public enum AccountRole {
// ordinal соответсвенно 10, 20, 30
ROOT, USERMANAGER, USERVIEWER
}
@Entity
@Table(name = "ACCOUNT_GROUP")
public class AccountGroup {
@Id
@Column(name = "AG_ID", nullable = false, unique = true)
private Integer groupId;
@Column(name = "AG_NAME", nullable = false, unique = true, length = 32)
private String groupName;
@Enumerated(EnumType.ORDINAL)
@ElementCollection(targetClass = AccountRole.class)
@CollectionTable(name = "GROUP_ROLE",
joinColumns = @JoinColumn(name = "AG_ID"))
@Column(name = "ROLE_ID")
private Set<AccountRole> roles = new HashSet<>();
...
}
AccountGroup group = new AccountGroup();
group.setGroupName("ABCDE");
group.setGroupId(101);
group.getRoles().add(AccountRole.ROOT);
group.getRoles().add(AccountRole.USERMANAGER);
accountGroupRepository.save(group);
private Enum[] enumsByOrdinal() {
if ( enumsByOrdinal == null ) {
enumsByOrdinal = enumClass.getEnumConstants();
if ( enumsByOrdinal == null ) {
throw new HibernateException( "Failed to init enum values" );
}
}
return enumsByOrdinal;
}
private Enum fromOrdinal(int ordinal) {
final Enum[] enumsByOrdinal = enumsByOrdinal();
if ( ordinal < 0 || ordinal >= enumsByOrdinal.length ) {
throw new IllegalArgumentException(
String.format(
"Unknown ordinal value [%s] for enum class [%s]",
ordinal,
enumClass.getName()
)
);
}
return enumsByOrdinal[ordinal];
}
JPA: Хранение перечислений в базе данных