Hibernate:混合动态(基于映射)和静态(基于Bean)映射
我正在开发一个程序来存储和管理测试结果。测试具有日期、持续时间和结果等属性。然而,有些测试测量压力,有些测试测量温度。。。我希望你能明白。因此,并非每个测试都具有相同的属性 我的第一个想法是将测试结果从测试表中提取到各个结果表中,从而创建1:1的关系。为了保持测试结果的可扩展性,我希望将结果存储在映射中,而不是bean中 然而,Hibernate似乎不喜欢我的方法。有人有过这种映射的经验吗?有更好的选择吗Hibernate:混合动态(基于映射)和静态(基于Bean)映射,hibernate,Hibernate,我正在开发一个程序来存储和管理测试结果。测试具有日期、持续时间和结果等属性。然而,有些测试测量压力,有些测试测量温度。。。我希望你能明白。因此,并非每个测试都具有相同的属性 我的第一个想法是将测试结果从测试表中提取到各个结果表中,从而创建1:1的关系。为了保持测试结果的可扩展性,我希望将结果存储在映射中,而不是bean中 然而,Hibernate似乎不喜欢我的方法。有人有过这种映射的经验吗?有更好的选择吗 编辑示例和进一步解释 -------- | Test | |id | +
编辑示例和进一步解释
--------
| Test |
|id |
+--------+
|date |
|duration| 1 1 ----------
|... | --------- | Medium |
-------- |testID |
+----------+
|medium |
|pressure |
----------
介质将是测试可以拥有的一个属性。由于可以添加其他属性,我不想硬编码中间类,而是将其映射为映射,存储这三个属性。我的想法是,测试将有一个映射
来表示与它相关的所有属性
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hoerbiger.versuchsdb.domain">
<class name="Test" lazy="false">
<id name="id">
<generator class="native"/>
</id>
<property name="datum"/>
<many-to-one name="material" class="Material"/>
<set name="testgeraete" table="Test_Testgeraet" lazy="false">
<key column="testID"/>
<many-to-many column="geraetID" class="Testgeraet"/>
</set>
<!-- Here it's getting important -->
<one-to-one name="medium" entity-name="Medium" constrained="false" lazy="false"
access="com.hoerbiger.versuchsdb.hibernate.TestAccessor"/>
</class>
</hibernate-mapping>
为了尝试有效的方法,我使用了这个主要方法。注意最后几行
@SuppressWarnings("unchecked")
public static void main(String[] args) {
Session s = Helper.getSessionfactory().getCurrentSession();
s.beginTransaction();
//Change to dynamic session
s = s.getSession(EntityMode.MAP);
Map<String, Object> test = (Map<String, Object>) s.createQuery("from Test").iterate().next();
//for me, prints "25"
System.out.println(test.get("id"));
Map<String, Object> medium = new HashMap<String, Object>();
medium.put("id", test);
medium.put("medium", "Luft");
medium.put("pressure", 40);
s.save("Medium", medium);
s.getTransaction().commit();
System.out.println("---");
s = Helper.getSessionfactory().getCurrentSession();
s.beginTransaction();
Test t = (Test) s.createQuery("from Test").iterate().next();
//for me, prints "null, 2010-07-07 00:00:00.0" (Test.toString())
System.out.println(t);
//"25"
System.out.println(t.getId());
//"{medium={id=null, 2010-07-07 00:00:00.0, ...}}"
System.out.println(t.getProperties());
//"true"
System.out.println(t.getProperties().get("medium").get("id") == t);
//This is really weird - hibernate loads the map with a Test stored, but when
//saving, it expects a Long. With this line, the Commit succeeds
t.getProperties().get("medium").put("id", t.getId());
s.getTransaction().commit();
}
@SuppressWarnings(“未选中”)
公共静态void main(字符串[]args){
会话s=Helper.getSessionfactory().getCurrentSession();
s、 beginTransaction();
//更改为动态会话
s=s.getSession(EntityMode.MAP);
Map test=(Map)s.createQuery(“来自测试”).iterate().next();
//对我来说,打印“25”
System.out.println(test.get(“id”));
Map medium=新的HashMap();
中等。放置(“id”,测试);
中档。卖出(“中档”、“中档”);
中等。放置(“压力”,40);
s、 保存(“中等”,中等);
s、 getTransaction().commit();
System.out.println(“--”);
s=Helper.getSessionfactory().getCurrentSession();
s、 beginTransaction();
Test t=(Test)s.createQuery(“来自测试”).iterate().next();
//对我来说,打印“null,2010-07-07 00:00:00.0”(Test.toString())
系统输出打印ln(t);
//"25"
System.out.println(t.getId());
//{medium={id=null,2010-07-07 00:00:00.0,…}
System.out.println(t.getProperties());
//“对”
System.out.println(t.getProperties().get(“medium”).get(“id”)==t);
//这真的很奇怪-hibernate加载地图时存储了一个测试,但是
//保存时,需要较长的时间。有了这一行,提交成功
t、 getProperties().get(“medium”).put(“id”,t.getId());
s、 getTransaction().commit();
}
最后几行是怎么回事?这是hibernate中的错误还是配置错误?经过进一步阅读,我发现了我的错误:目前,我的媒体映射如下所示:
<hibernate-mapping package="com.hoerbiger.versuchsdb.domain">
<class entity-name="Medium" lazy="false">
<id name="id" type="long">
<generator class="foreign">
<param name="property">id</param>
</generator>
</id>
<one-to-one name="id" class="Test" constrained="true"/>
<property name="medium" type="string"/>
<property name="pressure" type="int"/>
</class>
</hibernate-mapping>
<hibernate-mapping package="com.hoerbiger.versuchsdb.domain">
<class entity-name="Medium" lazy="false">
<id name="id" type="long">
<generator class="foreign">
<param name="property">test</param>
</generator>
</id>
<one-to-one name="test" class="Test" constrained="true"/>
<property name="medium" type="string"/>
<property name="pressure" type="int"/>
</class>
</hibernate-mapping>
身份证件
但它应该是这样的:
<hibernate-mapping package="com.hoerbiger.versuchsdb.domain">
<class entity-name="Medium" lazy="false">
<id name="id" type="long">
<generator class="foreign">
<param name="property">id</param>
</generator>
</id>
<one-to-one name="id" class="Test" constrained="true"/>
<property name="medium" type="string"/>
<property name="pressure" type="int"/>
</class>
</hibernate-mapping>
<hibernate-mapping package="com.hoerbiger.versuchsdb.domain">
<class entity-name="Medium" lazy="false">
<id name="id" type="long">
<generator class="foreign">
<param name="property">test</param>
</generator>
</id>
<one-to-one name="test" class="Test" constrained="true"/>
<property name="medium" type="string"/>
<property name="pressure" type="int"/>
</class>
</hibernate-mapping>
试验
问题是在生成器中使用“id”和一对一约束
Hibernate使用两个属性表示主键一对一约束,在我的例子中:
- id是PK&FK,即test.getId(),一个长
- test是对其自身的异物的引用
由于映射不是类型安全的,因此可以通过测试覆盖长时间存储的映射。这两个值只需读入同一映射条目即可。通过将id的两个匹配项更改为test,引用有自己的条目,不再覆盖id值如果关系为1:1,为什么需要映射?我认为展示一些Java代码(一个基本示例)将有助于理解您想要实现什么。另外,您使用的是XML映射还是注释?Hibernate的哪个版本(JPA2.O之前的版本与否)?嗨!谢谢你的帮助,在尝试完善我的问题时,我学到了很多。我使用的是3.5.3,我会将我的问题编辑成现在出了什么问题