| When using the JPA 2.1 interfaces, I am not receiving an EntityExistsException when an item is persisted. Here is my testcase code that demonstrates the behavior: /**
- Test for {@link Item#persist()}
*/ public void testPersist() { try
Unknown macro: { try (final java.io.InputStream inputStream = ItemImplTestCase.class .getResourceAsStream("/org/apache/auction/config/logging.properties")) { java.util.logging.LogManager.getLogManager().readConfiguration(inputStream); } catch (final java.io.IOException exception) { exception.printStackTrace(System.err); } final AuctionManager manager = AuctionManager.newInstance(); final Category category = manager.findCategory(1L); // manager.findItem(2L); final Item item = manager.newItem(); item.setName("testPersist"); item.setDescription("testPersist"); item.setCategory(category); // test initial persist item.persist(); // test update item.setName("testPersistUpdated"); item.persist(); Assert.assertEquals("testPersistUpdated", item.getName()); }
catch (final AuctionException exception) { exception.printStackTrace(System.err); TestCase.fail(exception.getLocalizedMessage()); } }
The Item.persist method is implemented as follows: public final void persist() throws AuctionException { final EntityManager manager = AuctionManagerImpl.newEntityManager(); final EntityTransaction transaction = manager.getTransaction(); try { transaction.begin(); if (this.getIdentifier() == null) { manager.persist(this); } else { manager.merge(this); } manager.flush(); transaction.commit(); } catch (final EntityExistsException exception) { transaction.rollback(); throw new AuctionException(exception); } finally { manager.close(); } } When I execute the test the first time, the database assigns an identifier of 2. When the test terminates the database still holds a row with that identifier. When I re-execute the test, the identifier is generated with the same value (it has located the row in the database) and an EntityExistsException is not thrown. The cause of this seems to be that I have a script that preloads a root entry into another table. This entry must have identifier = 1. It must be inserted directly into the table prior to test execution because that table has a parent/child foreign key that necessitates a TOP level object that can't be set at runtime. I then update the generated hibernate_sequence nextval to 2 to avoid re-use of the 1 value. When the identifier generator code runs, it provides the identifier of 2 to the new object. It appears when persisting this object, the code identifies the row as existing and does not attempt an insert. Hence no EntityExistsException is identified. |