有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在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; } }

因此,extproperty的类型是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持久化到扩展列

Tags:  

共 (1) 个答案

  1. # 1 楼答案

    您在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),将值序列化为字节数组,或使值成为自定义实体