繁体   English   中英

如何在Hibernate中保留动态扩展属性?

[英]How to persist dynamic extension property in Hibernate?

我面临着一个复杂的要求,这让我很困惑。 救命...

休眠:4.3.6 MySql 5.6.21

为了支持对标准产品的动态扩展,例如:标准POJO:

 package com.inspur.gsp; import java.util.HashMap; import java.util.Map; public class Person { private String id; private String age; private Map<CustomPK, Person_T> i18nProperty = new HashMap<CustomPK, Person_T>(); private Map<String, HashMap<String, Object>> extProperty = new HashMap<String, HashMap<String, Object>>(); public Map<CustomPK, Person_T> getI18nProperty() { return i18nProperty; } public void setI18nProperity(Map<CustomPK, Person_T> i18nProperty) { this.i18nProperty = i18nProperty; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public Map<String, HashMap<String, Object>> getExtProperty() { return extProperty; } public void setExtProperty(Map<String, HashMap<String, Object>> extProperty) { this.extProperty = extProperty; } } 

因此,ExtProperity的类型为Map<String, Map<String, Object>> ,它将用于存储扩展属性。 然后,我们需要将其持久保存到数据库中。

这是我的hbm.xml:

 <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated Nov 3, 2014 11:48:31 AM by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.inspur.gsp.Person" table="GSPPerson"> <id name="id" type="java.lang.String"> <column name="ID" length="36" /> <generator class="assigned" /> </id> <property name="age" type="java.lang.String"> <column name="age" length="128" /> </property> <map name="i18nProperty" table="GSPPerson_T"> <key column="ID"></key> <composite-map-key class="com.inspur.gsp.CustomPK"> <key-property name="culture"></key-property> </composite-map-key> <composite-element class="com.inspur.gsp.Person_T"> <property name="description" column="description"></property> <property name="comments" column="comments"></property> </composite-element> </map> <map name="extProperty" table="GSPPerson_Ext"> <key column="ID"></key> <map-key type="string" column="ID" /> <composite-element class="java.util.HashMap"> <property name="ext1" column="ext1"></property> <property name="ext2" column="ext2"></property> </composite-element> </map> </class> </hibernate-mapping> 

测试代码:

 SessionFactory sf = createSessionFactory(); Person person = new Person(); person.setId("1"); person.setAge("30"); HashMap<CustomPK, Person_T> i18nProperity = new HashMap<CustomPK, Person_T>(); Person_T t1 = new Person_T(); t1.setComments("abc"); t1.setDescription("description"); Person_T t2 = new Person_T(); t2.setComments("efg"); t2.setDescription("ooooooo"); i18nProperity.put(new CustomPK("1", "cn"), t1); i18nProperity.put(new CustomPK("1", "en"), t2); person.setI18nProperity(i18nProperity); HashMap<String, HashMap<String,Object>> extProperty = new HashMap<String, HashMap<String,Object>>(); HashMap<String,Object> e1 = new HashMap<String,Object>(); e1.put("ext1", 1); e1.put("ext2", "c001"); extProperty.put("1", e1);//1 is person's id ,e1 is extension property. person.setExtProperty(extProperty); Session session = sf.getCurrentSession(); Transaction ts = session.beginTransaction(); session.save(person); Person person2 = (Person) session.get(Person.class, "1"); ts.commit(); 

hbm.xml中的配置无法正常工作。 请帮我。 谢谢。

 INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect Exception in thread "main" org.hibernate.PropertyNotFoundException: field [ext1] not found on java.util.HashMap at org.hibernate.property.DirectPropertyAccessor.getField(DirectPropertyAccessor.java:166) at org.hibernate.property.DirectPropertyAccessor.getField(DirectPropertyAccessor.java:173) at org.hibernate.property.DirectPropertyAccessor.getField(DirectPropertyAccessor.java:158) at org.hibernate.property.DirectPropertyAccessor.getGetter(DirectPropertyAccessor.java:181) at org.hibernate.internal.util.ReflectHelper.getter(ReflectHelper.java:254) at org.hibernate.internal.util.ReflectHelper.reflectedPropertyClass(ReflectHelper.java:230) at org.hibernate.mapping.SimpleValue.setTypeUsingReflection(SimpleValue.java:362) at org.hibernate.cfg.HbmBinder.createProperty(HbmBinder.java:2350) at org.hibernate.cfg.HbmBinder.bindComponent(HbmBinder.java:2037) at org.hibernate.cfg.HbmBinder.bindComposite(HbmBinder.java:1836) at org.hibernate.cfg.HbmBinder.bindCollectionSecondPass(HbmBinder.java:2634) at org.hibernate.cfg.HbmBinder.bindMapSecondPass(HbmBinder.java:2468) at org.hibernate.cfg.HbmBinder$MapSecondPass.secondPass(HbmBinder.java:2843) at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:70) at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1695) at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1424) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844) at I18nTest.createSessionFactory(I18nTest.java:84) at I18nTest.main(I18nTest.java:37) 

GSPPerson的表结构为:

ID      Age    
1       30     

GSPPerson_ext的表结构为:

ID   ext1    ext2
1    1       c001

HashMap<String, HashMap<String,Object>> extProperty = new HashMap<String, HashMap<String,Object>>();
        HashMap<String,Object> e1 = new HashMap<String,Object>();
        e1.put("ext1", 1);
        e1.put("ext2", "c001");

        extProperty.put("1", e1);//1 is person's,e1 is extension property.
        person.setExtProperty(extProperty);

Ext1和Ext2是扩展列,因此我们定义了Hashmap<String,HashMap<String,Object>来存储扩展列。 我们希望将Hashmap保留到扩展列。

您正在HashMap上定义属性ext1 ,但它没有,因此Hibernate将查找这些属性。 ext1到底是什么意思?

此外,您要将Object放入地图中,而Hibernate无法将其映射。

我不确定您使用的是什么扩展,也不知道嵌套映射的键代表什么,但是我可能会将扩展建模为单独的实体。 像这样:

class Extension {
  String key;
  Type type; //Type could be an Enum, String, a Number etc. whatever fits your needs
  String value; //use a text representation of the values and convert according to the type
}

在您的Person类中:

Map<String, Extension> extensions = ...;

如您所见,我将扩展值映射到String而不是Object ,以允许Hibernate正确映射该值。 无论如何,大多数类型(至少是原语)都可以在字符串之间来回转换,所以这不是问题。 如果值变得更复杂,则需要适当的字符串映射(例如JSON或XML),将值序列化为字节数组或使值成为自定义实体。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM