Andy, thanks for you input.
I am trying your last solution. The actual classes are shown below. The DB
is oracle 10g. I am running the test using the following code to create a
book then looking up the book and trying to add a couple pages. The SQL
generate is exactly as you suspected and shown below. I get an Optimistic
locking error when trying to commit the updates (added pages). Do you see
what might be wrong?
//First, just create a book and a couple pages - works fine
EntityManager em = MyPersistence.getInstance().createEntityManager();
em.getTransaction().begin();
PageOfBook p1 = new PageOfBook();
p1.setData("This is a page 1 in a book");
PageOfBook p2 = new PageOfBook();
p2.setData("This is a page 2 in a book");
Book b = new Book("My Book Example for Lists");
b.getPages().add(p1);
b.getPages().add(p2);
em.persist(b);
em.getTransaction().commit();
//WORKS GREAT UP TO HERE - RECORDS GET WRITTEN TO DB AND OrderColumn is
creating a numbered sequence!
//Now, I am testing if I can add to the list, look up the saved book
em.getTransaction().begin();
//Query q3 = em.createQuery("SELECT book from Book book where book.id =
?1");
//q3.setParameter(1,1L);
//Book book = (Book) q3.getSingleResult();
BOTH THE QUERY AND THE EM.FIND RESULT IN Optimistic locking error exception
Book book = em.find(Book.class, 1L);
PageOfBook p3 = new PageOfBook();
p3.setData("This is a page 3 in a book");
PageOfBook p4 = new PageOfBook();
p3.setData("This is a page 4 in a book");
book.getPages().add(p3);
book.getPages().add(p4);
em.getTransaction().commit();
//on this commit, I get
Exception in thread "main" <openjpa-1.2.0-r422266:683325 fatal store error>
org.apache.openjpa.persistence.RollbackException: Optimistic locking errors
were detected when flushing to the data store. The following objects may
have been concurrently modified in another transaction:
[com.play.cmsdata.PageOfBook@5f55b990, com.play.cmsdata.PageOfBook@4319b06e]
at
org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.ja
va:523)
at hellojpa.Main.createBook(Main.java:122)
at hellojpa.Main.main(Main.java:37)
Caused by: <openjpa-1.2.0-r422266:683325 nonfatal store error>
org.apache.openjpa.persistence.OptimisticLockException: Optimistic locking
errors were detected when flushing to the data store. The following objects
may have been concurrently modified in another transaction:
[com.play.cmsdata.PageOfBook@5f55b990, com.play.cmsdata.PageOfBook@4319b06e]
at
org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2160)
at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2010)
at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1908)
at
org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:1826)
at
org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.jav
a:81)
at org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1350)
at
org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:877)
at
org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.ja
va:512)
... 2 more
Caused by: <openjpa-1.2.0-r422266:683325 nonfatal store error>
org.apache.openjpa.persistence.OptimisticLockException: An optimistic lock
violation was detected when flushing object instance
"com.play.cmsdata.PageOfBook@5f55b990" to the data store. This indicates
that the object was concurrently modified in another transaction.
FailedObject: com.play.cmsdata.PageOfBook@5f55b990
em.close();
-----------------------------------------------------------
import org.apache.openjpa.persistence.jdbc.OrderColumn;
import org.apache.openjpa.persistence.PersistentCollection;
import javax.persistence.*;
import java.util.List;
import java.util.ArrayList;
@Entity
@SequenceGenerator(name="BookSeq", sequenceName="BOOK_SEQ")
public class Book {
@Id @GeneratedValue(strategy= GenerationType.TABLE, generator="BookSeq")
private long id;
String title;
@PersistentCollection(elementCascade=CascadeType.ALL)
@OrderColumn
private List<PageOfBook> pages = new ArrayList<PageOfBook>();
public Book() {
}
public Book(long id) {
this.id = id;
}
public Book(String title) {
this.title = title;
}
public long getId() {
return id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<PageOfBook> getPages() {
return pages;
}
public void setPages(List<PageOfBook> pages) {
this.pages = pages;
}
}
-----------------------------------------------------------
import javax.persistence.*;
import javax.persistence.Lob;
import javax.persistence.GeneratedValue;
@Entity
@SequenceGenerator(name="PageOfBookSeq", sequenceName="PAGEOFBOOK_SEQ")
public class PageOfBook {
@Id @GeneratedValue(strategy= GenerationType.TABLE,
generator="PageOfBookSeq")
private long id;
@Lob
private String data;
public PageOfBook() {
}
public long getId() {
return id;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
Here are the actual generated tables (from sql trace):
CREATE TABLE Book (id NUMBER NOT NULL, title VARCHAR2(255), PRIMARY KEY
(id))
CREATE TABLE Book_PageOfBook (BOOK_ID NUMBER, PAGES_ID NUMBER, ordr NUMBER)
CREATE TABLE PageOfBook (id NUMBER NOT NULL, data CLOB, PRIMARY KEY (id))
|