好的,这将是很长的,所以这里是tl;dr
:当启用分布式缓存协调时,其中一个应用程序的完整性会慢慢降低并引发一个非常奇怪的异常。修复'是禁用缓存。哪个很烂。请帮助我们在EclipseLink中找到问题,以便我们对其进行修补!
EclipseLink 2.5.1
我们有这些实体:
@MappedSuperclass
public abstract class Identifiable implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "id", nullable = false, updatable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer id;
@Version
@Column(name = "meta__version")
private Integer version;
}
@Entity
@Table(name = "customers", indexes = { @Index(columnList = "phone_number"), @Index(columnList = "email_address") })
@Cacheable
public class Customer extends Identifiable {
private static final long serialVersionUID = 1L;
@Column(name = "last_name")
public String lastName;
@Column(name = "first_name")
public String firstName;
....
}
@Entity
@Table(name = "notes", indexes = { @Index(columnList = "customer_id, is_cleared") })
@Cacheable
public class Note extends Identifiable {
private static final long serialVersionUID = 1L;
@ManyToOne
@JoinColumn(name = "customer_id")
public Customer customer;
@ManyToOne
@JoinColumn(name = "agent_id")
public Agent agent;
@Size(min = 1, max = 32767)
@Column(name = "text", length = 32767)
public String text;
@Column(name = "is_cleared")
public Boolean isCleared;
}
<?xml version="1.0" encoding="UTF-8"?>
<persistence
version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="databunker">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/databunker</jta-data-source>
<mapping-file>databunker.orm.xml</mapping-file>
<class>com.mycompany.Customer</class>
<class>com.mycompany.Note</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
<!-- un-comment these properties to dump generated SQL -->
<!-- <property -->
<!-- name="eclipselink.logging.level.sql" -->
<!-- value="FINE" /> -->
<!-- <property -->
<!-- name="eclipselink.logging.parameters" -->
<!-- value="true" /> -->
<property
name="eclipselink.ddl-generation.output-mode"
value="database" />
<property
name="eclipselink.ddl-generation"
value="create-or-extend-tables" />
<property
name="eclipselink.weaving.changetracking"
value="false" />
<property
name="javax.persistence.query.timeout"
value="15000" />
<property
name="eclipselink.cache.size.default"
value="10000" />
<property
name="eclipselink.cache.coordination.protocol"
value="jms" />
<property
name="eclipselink.cache.coordination.jms.topic"
value="openejb:Resource/jms/EclipseLinkTopic" />
<property
name="eclipselink.cache.coordination.jms.factory"
value="openejb:Resource/jms/EclipseLinkTopicConnectionFactory" />
<property
name="eclipselink.cache.coordination.jms.reuse-topic-publisher"
value="true" />
<property
name="eclipselink.cache.coordination.remove-connection-on-error"
value="true" />
</properties>
</persistence-unit>
</persistence>
我们有两个应用程序。 App1在客户上编写/更新,App2在Notes上编写/更新。它们都使用完全相同的持久单元库jar。运行一段时间后,最终Notes应用程序开始因特定客户对象的堆栈跟踪而失败。重新启动服务器可以解决问题,直到另一个Customer对象开始发生。
[http-apr-8080-exec-1] ERROR c.mycompany.notes.restapi.RestExceptionMapper - toResponse() unexpected exception
javax.transaction.RollbackException: Unable to commit: transaction marked for rollback
at org.apache.geronimo.transaction.manager.TransactionImpl.commit(TransactionImpl.java:272) ~[geronimo-transaction-3.1.1.jar:3.1.1]
at org.apache.geronimo.transaction.manager.TransactionManagerImpl.commit(TransactionManagerImpl.java:252) ~[geronimo-transaction-3.1.1.jar:3.1.1]
at org.apache.openejb.core.transaction.JtaTransactionPolicy.completeTransaction(JtaTransactionPolicy.java:328) ~[openejb-core-4.6.0.1.jar:4.6.0.1]
at org.apache.openejb.core.transaction.TxRequired.commit(TxRequired.java:75) ~[openejb-core-4.6.0.1.jar:4.6.0.1]
at org.apache.openejb.core.transaction.EjbTransactionUtil.afterInvoke(EjbTransactionUtil.java:76) ~[openejb-core-4.6.0.1.jar:4.6.0.1]
at org.apache.openejb.core.stateless.StatelessContainer._invoke(StatelessContainer.java:231) ~[openejb-core-4.6.0.1.jar:4.6.0.1]
at org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:181) ~[openejb-core-4.6.0.1.jar:4.6.0.1]
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod(EjbObjectProxyHandler.java:268) ~[openejb-core-4.6.0.1.jar:4.6.0.1]
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:263) ~[openejb-core-4.6.0.1.jar:4.6.0.1]
at org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:86) ~[openejb-core-4.6.0.1.jar:4.6.0.1]
at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:303) ~[openejb-core-4.6.0.1.jar:4.6.0.1]
at com.sun.proxy.$Proxy108.getNotes(Unknown Source) ~[na:na]
at com.mycompany.notes.restapi.NoteTakerController.getNotes(NoteTakerController.java:68) ~[NoteTakerController.class:na]
at com.mycompany.notes.restapi.NoteTakerController$$OwbNormalScopeProxy0.getNotes(com/mycompany/notes/restapi/NoteTakerController.java) ~[na:na]
at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_60]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_60]
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:180) ~[cxf-api-2.6.9.jar:2.6.9]
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96) ~[cxf-api-2.6.9.jar:2.6.9]
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:165) [cxf-rt-frontend-jaxrs-2.6.9.jar:2.6.9]
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:89) [cxf-rt-frontend-jaxrs-2.6.9.jar:2.6.9]
at org.apache.openejb.server.cxf.rs.AutoJAXRSInvoker.invoke(AutoJAXRSInvoker.java:66) [openejb-cxf-rs-4.6.0.1.jar:4.6.0.1]
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:57) [cxf-api-2.6.9.jar:2.6.9]
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:93) [cxf-api-2.6.9.jar:2.6.9]
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262) [cxf-api-2.6.9.jar:2.6.9]
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) [cxf-api-2.6.9.jar:2.6.9]
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:237) [cxf-rt-transports-http-2.6.9.jar:2.6.9]
at org.apache.openejb.server.cxf.rs.CxfRsHttpListener.onMessage(CxfRsHttpListener.java:170) [openejb-cxf-rs-4.6.0.1.jar:4.6.0.1]
at org.apache.openejb.server.rest.RsServlet.service(RsServlet.java:53) [openejb-rest-4.6.0.1.jar:4.6.0.1]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) [servlet-api.jar:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) [catalina.jar:7.0.53]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.53]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat7-websocket.jar:7.0.53]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.53]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.53]
at com.mycompany.notes.restapi.security.HMACSecurityFilter.doFilter(HMACSecurityFilter.java:79) [HMACSecurityFilter.class:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.53]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.53]
at com.mycompany.cdi.RequestBufferingFilter.doFilter(RequestBufferingFilter.java:50) [java-common-1.0.10.jar:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.53]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.53]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) [catalina.jar:7.0.53]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) [catalina.jar:7.0.53]
at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45) [tomee-catalina-1.6.0.1.jar:1.6.0.1]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) [catalina.jar:7.0.53]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) [catalina.jar:7.0.53]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) [catalina.jar:7.0.53]
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) [catalina.jar:7.0.53]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) [catalina.jar:7.0.53]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) [catalina.jar:7.0.53]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040) [tomcat-coyote.jar:7.0.53]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607) [tomcat-coyote.jar:7.0.53]
at org.apache.tomcat.util.net.AprEndpoint$SocketWithOptionsProcessor.run(AprEndpoint.java:2378) [tomcat-coyote.jar:7.0.53]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_60]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_60]
at java.lang.Thread.run(Thread.java:745) [na:1.7.0_60]
Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-7197] (Eclipse Persistence Services - 2.5.2.v20131113-a7346c6): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Null or zero primary key encountered in unit of work clone [Customer[agent=Agent[agentName=Api User,id=1,version=1],address=Address[streetAddress=somewhere road,city=KANSAS CITY,zipcode=66210,state=State[postalAbbreviation=KS,id=38,version=1],id=298219,version=1],leadStatus=LeadStatus[name=New,id=1,version=1],leadSource=LeadSource[name=IRMS,id=9,version=1],project=Project[campaignName=Outbound59734,id=2,version=1],version=7]], primary key [null]. Set descriptors IdValidation or the "eclipselink.id-validation" property.
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl$1.handleException(EntityManagerSetupImpl.java:696) ~[eclipselink-2.5.2-M1.jar:2.5.2.v20131113-a7346c6]
at org.eclipse.persistence.transaction.AbstractSynchronizationListener.handleException(AbstractSynchronizationListener.java:275) ~[eclipselink-2.5.2-M1.jar:2.5.2.v20131113-a7346c6]
at org.eclipse.persistence.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:170) ~[eclipselink-2.5.2-M1.jar:2.5.2.v20131113-a7346c6]
at org.eclipse.persistence.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:68) ~[eclipselink-2.5.2-M1.jar:2.5.2.v20131113-a7346c6]
at org.apache.geronimo.transaction.manager.TransactionImpl.beforeCompletion(TransactionImpl.java:527) ~[geronimo-transaction-3.1.1.jar:3.1.1]
at org.apache.geronimo.transaction.manager.TransactionImpl.beforeCompletion(TransactionImpl.java:511) ~[geronimo-transaction-3.1.1.jar:3.1.1]
at org.apache.geronimo.transaction.manager.TransactionImpl.beforePrepare(TransactionImpl.java:413) ~[geronimo-transaction-3.1.1.jar:3.1.1]
at org.apache.geronimo.transaction.manager.TransactionImpl.commit(TransactionImpl.java:262) ~[geronimo-transaction-3.1.1.jar:3.1.1]
... 55 common frames omitted
Caused by: org.eclipse.persistence.exceptions.ValidationException:
Exception Description: Null or zero primary key encountered in unit of work clone [Customer[agent=Agent[agentName=Api User,id=1,version=1],address=Address[streetAddress=somewhere road,city=KANSAS CITY,zipcode=66210,state=State[postalAbbreviation=KS,id=38,version=1],id=298219,version=1],leadStatus=LeadStatus[name=New,id=1,version=1],leadSource=LeadSource[name=IRMS,id=9,version=1],project=Project[campaignName=Outbound59734,id=2,version=1],version=7]], primary key [null]. Set descriptors IdValidation or the "eclipselink.id-validation" property.
at org.eclipse.persistence.exceptions.ValidationException.nullPrimaryKeyInUnitOfWorkClone(ValidationException.java:1469) ~[eclipselink-2.5.2-M1.jar:2.5.2.v20131113-a7346c6]
at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.calculateChanges(DeferredChangeDetectionPolicy.java:109) ~[eclipselink-2.5.2-M1.jar:2.5.2.v20131113-a7346c6]
at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.calculateChangesForExistingObject(DeferredChangeDetectionPolicy.java:56) ~[eclipselink-2.5.2-M1.jar:2.5.2.v20131113-a7346c6]
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:664) ~[eclipselink-2.5.2-M1.jar:2.5.2.v20131113-a7346c6]
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1516) ~[eclipselink-2.5.2-M1.jar:2.5.2.v20131113-a7346c6]
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:3168) ~[eclipselink-2.5.2-M1.jar:2.5.2.v20131113-a7346c6]
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:352) ~[eclipselink-2.5.2-M1.jar:2.5.2.v20131113-a7346c6]
at org.eclipse.persistence.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:158) ~[eclipselink-2.5.2-M1.jar:2.5.2.v20131113-a7346c6]
... 60 common frames omitted
答案 0 :(得分:3)
Eclipselink默认执行分布式更新。尝试使用@Cache(coordinationType = CacheCoordinationType.INVALIDATE_CHANGED_OBJECTS)
答案 1 :(得分:1)
必须是深埋在EclipseLink内部的错误...禁用其他优化可以解决问题:
<property
name="eclipselink.weaving.internal"
value="false" />
糟糕,