Я работаю над программой для хранения и управления результатами теста. Тесты имеют свойства, такие как дата, продолжительность, а также результаты. Однако некоторые тесты измеряют давление, другие - температуру ... Надеюсь, вы поняли идею. Таким образом, не все тесты имеют одинаковые атрибуты.
Моей первой мыслью было извлечение результатов теста из таблицы тестов в отдельные таблицы результатов, таким образом создавая соотношение 1: 1. И чтобы результаты теста были расширяемыми, я хотел, чтобы результаты сохранялись в Картах, а не в Бинах.
Однако, похоже, что Hibernate не нравится мой подход. У кого-нибудь есть опыт работы с такого рода картографированием? Есть ли лучшая альтернатива?
РЕДАКТИРОВАТЬ для Пример и дальнейшее объяснение
--------
| Test |
|id |
+--------+
|date |
|duration| 1 1 ----------
|... | --------- | Medium |
-------- |testID |
+----------+
|medium |
|pressure |
----------
Среднее - это одно свойство, которое может иметь тест. Поскольку другие свойства могут быть добавлены, я не хочу жестко кодировать класс Medium, а скорее отобразить его как Map, сохраняя три атрибута. Я думал, что у Test будет Map<String, Map<String, Object>>
для представления всех связанных с ним свойств.
<?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>
Где com.hoerbiger.versuchsdb.hibernate.TestAccessor
- это PropertyAccessor для доступа к карте, которую я хочу использовать для отношений
<?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 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>
Чтобы попробовать, что работает, я использовал этот основной метод. Обратите внимание на последние несколько строк
@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();
}
Что за последние строки? Это ошибка в спящем режиме или неправильная конфигурация?