[ 
https://issues.apache.org/jira/browse/OPENJPA-2603?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Heath Thomann updated OPENJPA-2603:
-----------------------------------
    Attachment: OPENJPA-2603-2.1.x.patch

> Merging an unmanaged entity multiple (3) times leads to an exception.
> ---------------------------------------------------------------------
>
>                 Key: OPENJPA-2603
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-2603
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: jpa
>    Affects Versions: 2.1.2, 2.2.1.1, 2.2.3, 2.4.1
>            Reporter: Heath Thomann
>            Priority: Minor
>         Attachments: OPENJPA-2603-2.1.x.patch
>
>
> I have a scenario, albeit a very odd one, where by doing multiple 'merge' 
> calls on the same unmanaged entity causes an exception.  I say that it is an 
> 'odd' case because of the fact that an 'unmanaged' entity is being merged 
> multiple times.  The proper way to handle the scenario is to merge the 
> managed instance.  I'll attach a test to recreate/demonstrate the issue, but 
> for now here are code snippets we can use to explain the issue:
> @Entity
> @IdClass( LineItemPK.class )
> public class LineItem {
>       @Id
>       @Column( name = "ORDER_ID", nullable = false )
>       private Long orderId;
>       
>       @Id
>       @Column( name = "ITEM_ID", nullable = false )
>       private Long itemId;
> ......
> @Embeddable
> public class LineItemPK implements Serializable {
>       @Column( name = "ORDER_ID", nullable = false )
>       private Long orderId;
>       
>       @Column( name = "ITEM_ID", nullable = false )
>       private Long itemId;
> ......
> @Entity
> @Table( name = "ORDER_TABLE" )
> public class Order {
>       @Id 
>       @Column( name = "ID", nullable = false )
>       private Long id; 
>       @OneToMany( fetch = FetchType.EAGER, cascade = CascadeType.ALL )
>       @JoinColumn( name = "ORDER_ID", referencedColumnName = "ID" )
>       private List<LineItem> items;
> ......
> With these classes, take this test:
> em.getTransaction().begin();
> Order order = new Order( 1l );
>         
> LineItem item = new LineItem( "my product", 44, 4.99f );
> order.addItem(item);
> //NOTE: Notice that throughout the rest of the test the unmanaged order is 
> //merged.  Throughout the rest of the test we should do a 
> //'order = em.merge(order)', or something to that effect (i.e. use the 
> //'managed' order).  However, technically speaking merging the unmanaged 
> //order is not wrong, albeit odd and potentially error prone.        
> em.merge(order);
> em.getTransaction().commit();
> em.getTransaction().begin();
> LineItem additional = new LineItem( "My second product", 1, 999.95f );
> order.addItem(additional);
> order.setOrderEntry( new Date( System.currentTimeMillis() ) );
> em.merge(order);
> //NOTE: do a flush here and all works fine:
> //em.flush();
> em.merge(order);
> em.getTransaction().commit();
> As you can see, the unmanaged order is merged.  As my comments above suggest 
> this is odd, but technically not wrong.  What makes this case interesting is 
> that if we change LineItem to use a single PK rather than a compound PK, all 
> works fine!    The issue can also be resolve by performing a strategic 
> 'flush' as commented above.  Furthermore, the exception the above test yields 
> is:
> Caused by: <openjpa-2.1.2-SNAPSHOT-r422266:1686894M fatal general error> 
> org.apache.openjpa.persistence.PersistenceException: Column 'ORDER_ID'  
> cannot accept a NULL value. {prepstmnt 27085446 UPDATE ITEM_TABLE SET 
> ORDER_ID = ? WHERE ORDER_ID = ? [params=(null) null, (long) 1]} [code=20000, 
> state=23502]
> This is rather meaningless and is caused because OpenJPA executes this SQL 
> when doing the third merge:
> openjpa.jdbc.SQL - <t 3968441, conn 30267242> executing prepstmnt 27085446 
> UPDATE ITEM_TABLE SET ORDER_ID = ? WHERE ORDER_ID = ? [params=(null) null, 
> (long) 1]
> Given the odd message, and the fact that things work for the same exact 
> scenario when a single PK is used, and the fact that it can be resolved iwth 
> a 'flush', it makes sense to fix this issue.  
> Finally, I can't stress enough that the proper way to perform the above test 
> is to use the MANAGED version of the 'order'.  In other words, replace all 
> 'em.merge(order)' with 'order = em.merge(order)'.  The above scenario creates 
> far more SQL statements because of merging an unmanaged entity than if you 
> merged a managed entity.
> Thanks,
> Heath



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to