CompositeUserTypeを使用してHibernateのエンティティを接続する

投稿は短く、非常に技術的です。



挑戦する


内部に多数のORMエンティティ(エンティティ)があるJavaアプリケーションがあります。

ExtendedAttributesエンティティを実装する必要があります。これは、 追加の改良なしで他のエンティティにアタッチできます。



解決策


CompositeUserTypeは、バインドしたいエンティティのクラスとIDを含む私たちの助けになります。 それがソリューション全体です。 そして-コード。



投稿を減らすために、インポート、ゲッター、セッター、およびデフォルトのメソッドがクラスからカットされます。



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-存在しないエンティティのラッパー。

 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-これは同じ型です。 2つの文字列フィールドで構成され、GenericEntityを返します。

determinIdType()は唯一の本当の松葉杖ですが、私はまだ何を置き換えるべきかを見つけていません。

アプリケーションに他のタイプはありません。



 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); } } /** *  . Long/String/Double * * @param id * @return */ 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())); }
      
      







ご清聴ありがとうございました。 これが役に立つといいのですが:)



All Articles