Когда я пытаюсь добавить новый (несохраненный) Entities на один-ко-многим набор сохраненного родителя, после вызова Merge на родительском объекте, я получаю следующее исключение:
Предоставлено id неправильного типа для класса com.test.Child. Ожидаемый: класс java.lang.Long, есть класс org.hibernate.action.internal.DelayedPostInsertIdentifier
Я нашел билет, представляющий тот же вопрос: https://hibernate.atlassian.net/browse/HHH-2382 Он был отвергнут и не очень помогает с моим вопросом.
Неужели кто-нибудь сталкивался с этой проблемой? Может ли кто-нибудь указать источник проблемы и возможное решение?
Проблема в деталях:
У меня есть два класса: общественного класс Parent распространяется BaseModel реализует Serializable { частных длинного идентификатора; частные дети; }
public class Child extends BaseModel implements Serializable {
private long id;
private String value;
}
Я пытаюсь выполнить следующий код:
Parent parent = new Parent();
parent.setChildren(new HashSet<Child>());
Child child = new Child();
child.setValue("First");
parent.getChildren().add(child);
parent = daoFacade.save(parent);
child = new Child();
child.setValue("Second");
parent.getChildren().add(child);
parent = daoFacade.save(parent);
И после вызова метода сохранения во второй раз, я получаю следующее исключение:
org.hibernate.TypeMismatchException : Предоставлен идентификатор неправильного типа для класс com.text.Child. Ожидаемый: класс java.lang.Long, есть класс org.hibernate.action.internal.DelayedPostInsertIdentifier в org.hibernate.event.internal.DefaultLoadEventListener.onLoad (DefaultLoadEventListener.java:134) в org.hibernate.internal.SessionImpl .fireLoad (SessionImpl.java:1092) на org.hibernate.internal.SessionImpl.internalLoad (SessionImpl.java:1019) на org.hibernate.type.EntityType.resolveIdentifier (EntityType.java:648) в орг .hibernate.type.EntityType.resolve (EntityType.java:468) в org.hibernate.type.EntityType.replace (EntityType.java:325) в org.hibernate.type.CollectionType.replaceElements (CollectionType.java:517)) по адресу org.hibernate.type.Col lectionType.replace (CollectionType.java:667) на org.hibernate.type.TypeHelper.replace (TypeHelper.java:177) при org.hibernate.event.internal.DefaultMergeEventListener.copyValues (DefaultMergeEventListener.java:372) на org.hibernate.event.internal.DefaultMergeEventListener.entityIsPersistent (DefaultMergeEventListener.java:184) на org.hibernate.event.internal.DefaultMergeEventListener.onMerge (DefaultMergeEventListener.java:157) на org.hibernate.event.internal .DefaultMergeEventListener.onMerge (DefaultMergeEventListener.java:76) at org.hibernate.internal.SessionImpl.fireMerge (SessionImpl.java:914) at org.hibernate.internal.SessionImpl.merge (SessionImpl.java: 898) на org.hibernate.internal.SessionImpl.merge (SessionImpl.java:902) на com.test.DAOFacade.saveObject (DAOFacade.java:273) на com.test.Test.testSaving (MemcachedTest. Java: 99)
метод DaoFacade.save выглядит следующим образом:
public void saveOrUpdate(T obj) {
Session session = getSession();
BaseModel model = (BaseModel) obj;
if (model.isNew()) {
T merged = (T)session.merge(obj);
session.update(merged);
} else {
session.saveOrUpdate(obj);
}
session.flush();
}
Hibernate отображения являются:
<class name="Parent" table="PARENT">
<id name="id" column="id" unsaved-value="0">
<generator class="native"/>
</id>
<set name="children" inverse="false" lazy="false" cascade="all">
<cache usage="read-write" />
<key column="LINK_ID"/>
<one-to-many class="Child"/>
</set>
</class>
<class name="Child" table="CHILD">
<cache usage="read-write" />
<id name="id" column="id" unsaved-value="0">
<generator class="native"/>
</id>
<property name="value" type="string" column="VALUE" not-null="true" lazy="false"/>
</class>
Я отладки в течение нескольких часов и всего процесса эс, кажется, идет correclty в спящем режиме, но на самом деле это приводит к следующей задаче:
- Во время слияния, при переборе полех, несохраненный «Второй» Ребенок найдено.
- «Второй» Ребенок помечен для вставки, Вставка запроса подготовлена и помещается в QueryQueue.
- Продолжая процесс слияния, Спящий режим в какой-то момент пытается загрузить «Второго» Ребенка
- Но он еще не вставлен, а Excetchion поднят.
Мы не используем сделки, потому что мы используем на более высоком уровне: Нам нужно обновить и создать несколько объектов разных типов в рамках одной транзакции. И несколько раз мы просто не используем транзакции для несущественных объектов (где произошло исключение). Наверное, это источник проблемы. И нам нужно будет создать какой-то механизм и создать транзакцию только тогда, когда это необходимо. –
@ DmitriiSemenov, когда вы говорите, что используете транзакции на более высоком уровне, вы имеете в виду, что вы используете какую-то структуру управления транзакциями (например, Spring-spring-tx)? вы можете сказать мне, почему вы бы назвали метод saveOrUpdate или update без создания транзакции? – arjaynacion