我很确定我对 JPA 不了解(我正在使用 OpenJPA)并且它导致了这个问题。我想复制一个 Job 实体。
@Entity
@Table(name="Job")
public class Job implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@ManyToOne
private Job job;
@OneToMany(fetch = FetchType.EAGER)
private Set<Job> jobCollection;
...
public Job getJob() {
return this.job;
}
public void setJob(Job job) {
this.job = job;
}
public Set<Job> getCopies() {
return this.jobCollection;
}
public void setCopies(Set<Job> jobCollection) {
this.jobCollection = jobCollection;
}
}
在创建第一个副本时,运行以下代码可以正常工作。
public void testCopyJob(){
Job job = jobManager.findJobById(100);
Job jobWithCopies = null;
try {
jobWithCopies = jobManager.copyJob(job, "test copy");
} catch (Exception e) {
fail(e.getMessage());
}
Set<Job> copies = jobWithCopies.getCopies();
assertEquals("num copies", 1, copies.size());
//make a second copy
Job jobWithCopies2 = null;
try {
jobWithCopies2 = jobManager.copyJob(jobWithCopies, "test copy");
assertEquals("multiple copies", 2, jobWithCopies2.getCopies().size());
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
}
尝试创建第二个副本失败并...
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R <openjpa-1.2.1-SNAPSHOT-r422266:686069 fatal general error> org.apache.openjpa.persistence.PersistenceException: null
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1688)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.kernel.StateManagerImpl.assignObjectId(StateManagerImpl.java:523)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.kernel.StateManagerImpl.assignField(StateManagerImpl.java:608)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.kernel.StateManagerImpl.beforeAccessField(StateManagerImpl.java:1494)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.kernel.StateManagerImpl.accessingField(StateManagerImpl.java:1477)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at entities.Job.pcGetid(Job.java)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at entities.Job.hashCode(Job.java:402)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at java.util.HashMap.putImpl(Unknown Source)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at java.util.HashMap.put(Unknown Source)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at java.util.HashSet.add(Unknown Source)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.util.java$util$HashSet$proxy.add(Unknown Source)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at entities.controller.JobManager.copyJob(JobManager.java:140)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at entities.controller.JobManagerTest.testCopyJob(JobManagerTest.java:55)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:45)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at java.lang.reflect.Method.invoke(Method.java:599)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at junit.framework.TestCase.runTest(TestCase.java:154)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at junit.framework.TestCase.runBare(TestCase.java:127)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at junit.framework.TestResult$1.protect(TestResult.java:106)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at junit.framework.TestResult.runProtected(TestResult.java:124)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at junit.framework.TestResult.run(TestResult.java:109)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at junit.framework.TestCase.run(TestCase.java:118)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at junit.framework.TestSuite.runTest(TestSuite.java:208)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at junit.framework.TestSuite.run(TestSuite.java:203)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.cactus.server.runner.ServletTestRunner.run(ServletTestRunner.java:309)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.cactus.server.runner.ServletTestRunner.doGet_aroundBody0(ServletTestRunner.java:187)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.cactus.server.runner.ServletTestRunner.doGet_aroundBody1$advice(ServletTestRunner.java:225)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.cactus.server.runner.ServletTestRunner.doGet(ServletTestRunner.java:1)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at javax.servlet.http.HttpServlet.service(HttpServlet.java:718)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1449)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:790)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:443)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:175)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3610)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:274)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:926)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1557)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:173)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:455)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewInformation(HttpInboundLink.java:384)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:272)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:214)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:113)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:202)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:766)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:896)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1527)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R Caused by: java.lang.UnsupportedOperationException
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.kernel.DetachedStateManager.getMetaData(DetachedStateManager.java:696)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.jdbc.meta.strats.UntypedPCValueHandler.toRelationDataStoreValue(UntypedPCValueHandler.java:121)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.jdbc.sql.RowImpl.setRelationId(RowImpl.java:327)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.jdbc.sql.SecondaryRow.setRelationId(SecondaryRow.java:106)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.jdbc.meta.strats.HandlerStrategies.set(HandlerStrategies.java:150)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.jdbc.meta.strats.HandlerStrategies.set(HandlerStrategies.java:104)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.jdbc.meta.strats.HandlerCollectionTableFieldStrategy.insert(HandlerCollectionTableFieldStrategy.java:154)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.jdbc.meta.strats.HandlerCollectionTableFieldStrategy.insert(HandlerCollectionTableFieldStrategy.java:130)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.jdbc.meta.FieldMapping.insert(FieldMapping.java:579)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.insert(AbstractUpdateManager.java:197)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.populateRowManager(AbstractUpdateManager.java:139)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.persistence.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:73)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at com.ibm.ws.persistence.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:60)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:655)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:130)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2010)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1908)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1679)
[11/25/08 8:46:56:546 EST] 00000018 SystemErr R ... 52 more
在 JobManager.copyJob() 方法中抛出此异常(在行:attachJob.getCopies().add(newJob);)...
@JPAManager(targetEntity=entities.Job.class)
public class JobManager {
private EntityManager getEntityManager() {
EntityManagerFactory emf = Persistence
.createEntityManagerFactory("import");
return emf.createEntityManager();
}
@Action(Action.ACTION_TYPE.FIND)
public Job findJobById(int id) {
EntityManager em = getEntityManager();
Job job = null;
try {
job = (Job) em.find(Job.class, id);
} finally {
em.close();
}
return job;
}
public Job copyJob(Job job, String newJobName) throws Exception {
EntityManager em = getEntityManager();
Job attachedJob = null;
try {
em.getTransaction().begin();
//merge any changes made to job
attachedJob = em.merge(job);
//copy the job and establish bi-directional relationship
Job newJob = new Job(job);
newJob.setName(newJobName);
newJob.setJob(attachedJob);
em.persist(newJob);
attachedJob.getCopies().add(newJob);
em.getTransaction().commit(); //commit changes to original job
} catch (Exception ex) {
try {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
} catch (Exception e) {
ex.printStackTrace();
throw e;
}
throw ex;
} finally {
em.close();
}
return attachedJob;
}
}
这是我正在使用的生成的数据库模式......
CREATE TABLE Job (id INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY, JOB_ID INTEGER, PRIMARY KEY (id));
CREATE TABLE Job_jobCollection (JOB_ID INTEGER, element VARCHAR(254));
ALTER TABLE Job ADD FOREIGN KEY (JOB_ID) REFERENCES Job (id);
ALTER TABLE Job_jobCollection ADD FOREIGN KEY (JOB_ID) REFERENCES Job (id);
查看 OpenJPA 1.2 源代码显示未实现 DetachedStateManager.getMetaData() 方法,所以我想知道为什么要调用它。有小费吗??