рдкрдж рдЫреЛрдЯрд╛ рдФрд░ рдмрд╣реБрдд рд╣реА рддрдХрдиреАрдХреА рд╣реЛрдЧрд╛редрдХрд╛рд░реНрдп
рдПрдХ рдЬрд╛рд╡рд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ ORM рдЗрдХрд╛рдЗрдпрд╛рдВ (рдЗрдХрд╛рдИ) рдЕрдВрджрд░ рд╣реИрдВред
ExtendedAttributes рдирд┐рдХрд╛рдп рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдЬрд┐рд╕реЗ
рдЕрддрд┐рд░рд┐рдХреНрдд рд╢реЛрдзрди рдХреЗ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдЗрдХрд╛рдИ рд╕реЗ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛
рд╣реИ ред
рдирд┐рд░реНрдгрдп
CompiteUserType рд╣рдорд╛рд░реА рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рд▓рд┐рдП рдЖрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╡рд╣ рдЗрдХрд╛рдИ рдФрд░ рдЖрдИрдбреА рд╢рд╛рдорд┐рд▓ рд╣реЛрддреА рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рдмрд╛рдВрдзрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рд╡рд╣ рд╕рдВрдкреВрд░реНрдг рд╕рдорд╛рдзрд╛рди рд╣реИред рдФрд░ рдлрд┐рд░ - рдХреЛрдбред
рдкреЛрд╕реНрдЯ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдпрд╛рдд, рдЧреЗрдЯрд░реНрд╕, рд╕реЗрдЯрд░ рдФрд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рддрд░реАрдХреЛрдВ рдХреЛ рдХрдХреНрд╖рд╛рдУрдВ рд╕реЗ рдХрд╛рдЯ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
ExtendedAttributes.class - рдпрд╣ рд╣рдо рдЗрд╕ рдХрд╛рд░реНрдп рдХреЗ рднрд╛рдЧ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ
@Entity @Table(name = "extattributes") @TypeDef(name = "entityType", typeClass = hibernate.GenericEntityType.class) public class ExtendedAttributes extends GenericEntity { private static final long serialVersionUID = 1L; @Id private Long id; @Type(type = "entityType") @Columns(columns = { @Column(name = "object_id"), @Column(name = "object_class") }) private GenericEntity object; private String property; private String value; @Override public Class<?> getType() { return ExtendedAttributes.class; } @Override public Long getId() { return id; } }
GenericEntity.class - рдЗрд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд╕рднреА рдирд┐рдХрд╛рдп рдЗрд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рджреЗрддреЗ рд╣реИрдВред
public abstract class GenericEntity implements Serializable { private static final long serialVersionUID = 1L; public abstract Serializable getId(); public abstract Class<?> getType(); }
EntityWrapper.class - nonexistent рд╕рдВрд╕реНрдерд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╡рд░рдгред
public class EntityWrapper extends GenericEntity { private static final long serialVersionUID = 1L; private String name; public EntityWrapper(String name) { super(); this.name = name; } @Override public Serializable getId() { return name; } @Override public Class<?> getType() { return EntityWrapper.class; } }
GenericEntityType.class - рдФрд░ рдпрд╣рд╛рдБ рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рд╣реИред рджреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдлрд╝реАрд▓реНрдб рд╕реЗ рдорд┐рд▓рдХрд░, GenericEntity рджреЗрддрд╛ рд╣реИред
рджреГрдврд╝рдирд┐рд╢реНрдЪрдп () рдПрдХрдорд╛рддреНрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдмреИрд╕рд╛рдЦреА рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдЕрднреА рддрдХ рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдмрджрд▓рдирд╛ рд╣реИред
рдЖрдИрдбреА рдЖрд╡реЗрджрди рдореЗрдВ рдХреЛрдИ рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВред
public class GenericEntityType implements CompositeUserType { private static final Type[] SQL_TYPES = { StringType.INSTANCE, StringType.INSTANCE }; private static final String[] SQL_NAMES = { "id", "class" }; @Override public String[] getPropertyNames() { return SQL_NAMES; } @Override public Type[] getPropertyTypes() { return SQL_TYPES; } @Override public Class<?> returnedClass() { return GenericEntity.class; } @Override public boolean equals(Object o1, Object o2) throws HibernateException { if (o1 == o2) return true; if (o1 != null && o2 != null) return o1.equals(o2); return false; } @Override public Object getPropertyValue(Object object, int index) throws HibernateException { GenericEntity dto = (GenericEntity) object; if (index == 0) { return dto.getId(); } else if (index == 1) { return dto.getType(); } else { throw new HibernateException("Unknown index [ " + index + " ]"); } } @Override public int hashCode(Object object) throws HibernateException { return (object != null) ? object.hashCode() : 0; } @Override public boolean isMutable() { return false; } @Override public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException { if (names.length == 2) { String id = (String) StringType.INSTANCE.get(rs, names[0], session); String clazz = (String) StringType.INSTANCE.get(rs, names[1], session); if (id != null && clazz != null) { try { Class.forName(clazz); return session.immediateLoad(clazz, determineIdType(id)); } catch (ClassNotFoundException e) { return new EntityWrapper(id); } } } return null; } @Override public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException { if (value == null) { StringType.INSTANCE.set(st, null, index, session); ClassType.INSTANCE.set(st, null, index + 1, session); } else { final GenericEntity dto = (GenericEntity) value; StringType.INSTANCE.set(st, dto.getId().toString(), index, session); ClassType.INSTANCE.set(st, dto.getType(), index + 1, session); } } private Serializable determineIdType(String id) { try { if (id.matches("^\\d+$")) { return Long.valueOf(id); } else if (id.matches("^\\d+[\\.,]\\d+$")) { return Double.valueOf(id); } else { return id; } } catch (NumberFormatException e) { return id; } }
рдФрд░ рдЕрдм - рдХреИрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ:
public static Criterion criterionForEntity(String field, GenericEntity object) { String id = ""; if (object.getId() != null) { id = object.getId().toString(); } return Restrictions.and(Restrictions.eq(field + ".id", id), Restrictions.eq(field + ".class", object.getType() .getCanonicalName())); }
рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рдо рдЖрдПрдЧрд╛ :)