У меня есть новый (т.е. нет в базе данных еще нет) JPA объекта, который сохраняется в БД с этим битом кода:OpenJPA метания EntityExistsException нерегулярно
public abstract class Dao {
@PersistenceContext(name = "puOpenJPA_Core",type = PersistenceContextType.TRANSACTION)
private EntityManager em;
public void save(Fund entity) {
entity = em.merge(entity);
em.flush();
// do something with entity.fundId
}
}
Нам нужно flush
, потому что мы используем идентификатор объекта, чтобы заполнить что-то еще, и идентификатор создается в БД.
Лицо выглядит следующим образом:
@Entity
public class Fund extends AbstractFund implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "fundId")
protected Long id;
// other fields and getters etc.
}
AbstractFund
является абстрактным сопоставляются суперкласса, который имеет несколько полей.
В таблице базы данных есть столбец fundId
, определяемый как идентификатор. Это хорошо работает долгое время. Однако мы вызываем прерывистую ошибку, когда вызывается flush
. После развертывания код отлично работает на некоторое время, а потом вдруг начинает бросать это исключение:
Caused by: <openjpa-2.3.0-r422266:1540826 fatal general error> org.apache.openjpa.persistence.PersistenceException:
The transaction has been rolled back. See the nested exceptions for details on the errors that occurred.
FailedObject: [email protected]
at org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2370) [openjpa-all-2.3.0.jar:2.3.0]
at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2207) [openjpa-all-2.3.0.jar:2.3.0]
at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:2105) [openjpa-all-2.3.0.jar:2.3.0]
at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1876) [openjpa-all-2.3.0.jar:2.3.0]
at org.apache.openjpa.kernel.DelegatingBroker.flush(DelegatingBroker.java:1045) [openjpa-all-2.3.0.jar:2.3.0]
at org.apache.openjpa.persistence.EntityManagerImpl.flush(EntityManagerImpl.java:663) [openjpa-all-2.3.0.jar:2.3.0]
at org.jboss.as.jpa.container.AbstractEntityManager.flush(AbstractEntityManager.java:457) [wildfly-jpa-8.1.0.Final.jar:8.1.0.Final]
......
Caused by: java.lang.Exception: <openjpa-2.3.0-r422266:1540826 fatal store error> org.apache.openjpa.persistence.EntityExistsException:
Cannot insert explicit value for identity column in table 'Fund' when IDENTITY_INSERT is set to OFF. {prepstmnt 2128975916 INSERT INTO Fund
(fundId, ... other columns ...) VALUES (?, ?, ?,)} [code=544, state=23000]
FailedObject: [email protected]
at org.apache.openjpa.util.Exceptions.replaceNestedThrowables(Exceptions.java:255) [openjpa-all-2.3.0.jar:2.3.0]
at org.apache.openjpa.persistence.PersistenceException.writeObject(PersistenceException.java:100) [openjpa-all-2.3.0.jar:2.3.0]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_60]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_60]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_60]
at java.lang.reflect.Method.invoke(Method.java:606) [rt.jar:1.7.0_60]
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)
at org.jboss.marshalling.cloner.SerializingCloner.initSerializableClone(SerializingCloner.java:290)
at org.jboss.marshalling.cloner.SerializingCloner.clone(SerializingCloner.java:245)
at org.jboss.marshalling.cloner.SerializingCloner.clone(SerializingCloner.java:125)
at org.jboss.marshalling.cloner.SerializingCloner.cloneFields(SerializingCloner.java:341)
at org.jboss.marshalling.cloner.SerializingCloner.initSerializableClone(SerializingCloner.java:293)
at org.jboss.marshalling.cloner.SerializingCloner.initSerializableClone(SerializingCloner.java:277)
at org.jboss.marshalling.cloner.SerializingCloner.initSerializableClone(SerializingCloner.java:277)
at org.jboss.marshalling.cloner.SerializingCloner.initSerializableClone(SerializingCloner.java:277)
at org.jboss.marshalling.cloner.SerializingCloner.initSerializableClone(SerializingCloner.java:277)
at org.jboss.marshalling.cloner.SerializingCloner.clone(SerializingCloner.java:245)
at org.jboss.marshalling.cloner.SerializingCloner.clone(SerializingCloner.java:125)
at org.jboss.as.ejb3.remote.LocalEjbReceiver.clone(LocalEjbReceiver.java:314) [wildfly-ejb3-8.1.0.Final.jar:8.1.0.Final]
at org.jboss.as.ejb3.remote.LocalEjbReceiver.clone(LocalEjbReceiver.java:297) [wildfly-ejb3-8.1.0.Final.jar:8.1.0.Final]
at org.jboss.as.ejb3.remote.LocalEjbReceiver.processInvocation(LocalEjbReceiver.java:249) [wildfly-ejb3-8.1.0.Final.jar:8.1.0.Final]
... 126 more
Я был не в состоянии воссоздать это на других средах и нахожусь в недоумении, почему OpenJPA внезапно начинают пытаться вставить значение для столбца идентификации.
Мы используем OpenJPA версии 2.3.0.
Я пробовал обновление до версии 2.4.1, но проблема не устранена.
Сомневаюсь, если таблица 'Fund' уже есть некоторые старые строки, которая вызывает проблему? –
Кажется маловероятным - ошибка SQL весьма специфична, поскольку речь идет о вставке столбца идентификатора. –
Ошибка явная, она заявляет, что не может вставить значение в поле ID. Вы вызываете слияние на сущности, у которой уже установлено поле идентификатора. Что вы объединяете, когда получаете это исключение, и вы можете попробовать включить SQL-журнал, чтобы вы могли видеть вставки/обновления/удаления, чтобы отслеживать, почему у этого есть проблема. Я предполагаю, что вы удалили сущность и пытаетесь объединить ее обратно, и поле идентификации не позволит вам. – Chris