openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From CG <learn....@gmail.com>
Subject Cascade.Type misbehaviour for PERSIST in a for loop, extra UPDATE statement triggerred in the 2nd loop
Date Fri, 13 Feb 2009 06:41:51 GMT
Hi, I encounter a problem with CascadeType for a OneToMany
relationship, hopefully somebody can help ... Thanks.

I am using OpenJPA 1.0.3 that come with Apache Geronimo 2.1.3


Basically , I have a loop to create ProductionOrder and the
corresponding detail ProductionOrderMaterial
After debugging , it shows that in the 2nd loop , not only INSERT
statement is generated , there are several unnecessary UPDATE
statements triggered , cause PersistentException ..


Code
====

     for loop


		ProductionOrder productionOrder = new ProductionOrder();
					
		
		productionOrder.setDocNo("0");
		productionOrder.setQuantityOrder(node.getData().getTreeOriginalQuantityRequired()
* salesOrderMaterial.getQuantityOrder());
					
		productionOrder.setMaterial(node.getData().getBomDetail().getMaterial());
					
															
					
		for(TreeNode<BomTreeNodeData> child : productionOrderChildren)
		{
			ProductionOrderMaterial productionOrderMaterial = new
ProductionOrderMaterial();
						
			productionOrderMaterial.setQuantityConsumed(0.0);

			productionOrderMaterial.setCreateApp(rowInfo.getCreateApp());
			productionOrderMaterial.setModifyApp(rowInfo.getModifyApp());
			productionOrderMaterial.setCreateLogin(rowInfo.getCreateLogin());
			productionOrderMaterial.setModifyLogin(rowInfo.getModifyLogin());
			productionOrderMaterial.setSessionId(rowInfo.getSessionId());
						

                       // the below line will do a two-way link
between ProductionOrder and ProductionOrderMaterial
			productionOrder.addProductionOrderMaterial(productionOrderMaterial);

		}
	
      // this line will do a _em.persist				
      productionOrderService.addProductionOrder(productionOrder);

end for loop


DEBUG Log

First loop
============
SELECT KEYFIELD FROM PrimaryKeys WHERE TABLENAME = ? FOR UPDATE
[params=(String) ProductionOrder]
UPDATE PrimaryKeys SET KEYFIELD = ? WHERE TABLENAME = ? AND KEYFIELD =
? [params=(long) 950, (String) ProductionOrder, (long) 900]
SELECT KEYFIELD FROM PrimaryKeys WHERE TABLENAME = ? FOR UPDATE
[params=(String) ProductionOrderMaterial]
UPDATE PrimaryKeys SET KEYFIELD = ? WHERE TABLENAME = ? AND KEYFIELD =
? [params=(long) 950, (String) ProductionOrderMaterial, (long) 900]

INSERT INTO ProductionOrder (id_ProductionOrder, prodo_Number,
prodo_QuantityOrder, prodo_QuantityReported, version, fk_Material,
createApp, createLogin, createTimestamp, modifyApp, modifyLogin,
modifyTimestamp, recordStatus, sessionId, fk_SalesOrder) VALUES (?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [params=(long) 900, (String) 0,
(double) 50.0, (double) 0.0, (int) 1, (long) 100, (String) TestClient,
(String) test, (Timestamp) 2009-02-13 13:54:12.319, (String)
TestClient, (String) test, (Timestamp) 2009-02-13 13:54:12.319,
(String) A, (String) , (null) null]

INSERT INTO ProductionOrderMaterial (id_ProductionOrderMaterial,
prodom_QuantityConsumed, prodom_QuantityRequired, version,
fk_ProductionOrder, fk_Material, fk_ProductionOrderOperation,
createApp, createLogin, createTimestamp, modifyApp, modifyLogin,
modifyTimestamp, recordStatus, sessionId) VALUES (?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?) [params=(long) 900, (double) 0.0, (double)
100.0, (int) 1, (long) 900, (long) 101, (null) null, (String)
TestClient, (String) test, (Timestamp) 2009-02-13 13:54:12.32,
(String) TestClient, (String) test, (Timestamp) 2009-02-13
13:54:12.32, (String) A, (String) ABC]

INSERT INTO ProductionOrderMaterial (id_ProductionOrderMaterial,
prodom_QuantityConsumed, prodom_QuantityRequired, version,
fk_ProductionOrder, fk_Material, fk_ProductionOrderOperation,
createApp, createLogin, createTimestamp, modifyApp, modifyLogin,
modifyTimestamp, recordStatus, sessionId) VALUES (?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?) [params=(long) 901, (double) 0.0, (double)
150.0, (int) 1, (long) 900, (long) 102, (null) null, (String)
TestClient, (String) test, (Timestamp) 2009-02-13 13:54:12.32,
(String) TestClient, (String) test, (Timestamp) 2009-02-13
13:54:12.32, (String) A, (String) ABC]

2nd Loop
==========
INSERT INTO ProductionOrder (id_ProductionOrder, prodo_Number,
prodo_QuantityOrder, prodo_QuantityReported, version, fk_Material,
createApp, createLogin, createTimestamp, modifyApp, modifyLogin,
modifyTimestamp, recordStatus, sessionId, fk_SalesOrder) VALUES (?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [params=(long) 901, (String) 0,
(double) 100.0, (double) 0.0, (int) 1, (long) 101, (String)
TestClient, (String) test, (Timestamp) 2009-02-13 13:54:12.363,
(String) TestClient, (String) test, (Timestamp) 2009-02-13
13:54:12.363, (String) A, (String) , (null) null]

 INSERT INTO ProductionOrderMaterial (id_ProductionOrderMaterial,
prodom_QuantityConsumed, prodom_QuantityRequired, version,
fk_ProductionOrder, fk_Material, fk_ProductionOrderOperation,
createApp, createLogin, createTimestamp, modifyApp, modifyLogin,
modifyTimestamp, recordStatus, sessionId) VALUES (?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?) [params=(long) 902, (double) 0.0, (double)
1000.0, (int) 1, (long) 901, (long) 106, (null) null, (String)
TestClient, (String) test, (Timestamp) 2009-02-13 13:54:12.364,
(String) TestClient, (String) test, (Timestamp) 2009-02-13
13:54:12.364, (String) A, (String) ABC]

3 INSERT INTO ProductionOrderMaterial (id_ProductionOrderMaterial,
prodom_QuantityConsumed, prodom_QuantityRequired, version,
fk_ProductionOrder, fk_Material, fk_ProductionOrderOperation,
createApp, createLogin, createTimestamp, modifyApp, modifyLogin,
modifyTimestamp, recordStatus, sessionId) VALUES (?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?) [params=(long) 903, (double) 0.0, (double)
400.0, (int) 1, (long) 901, (long) 107, (null) null, (String)
TestClient, (String) test, (Timestamp) 2009-02-13 13:54:12.364,
(String) TestClient, (String) test, (Timestamp) 2009-02-13
13:54:12.364, (String) A, (String) ABC]

INSERT INTO ProductionOrderMaterial (id_ProductionOrderMaterial,
prodom_QuantityConsumed, prodom_QuantityRequired, version,
fk_ProductionOrder, fk_Material, fk_ProductionOrderOperation,
createApp, createLogin, createTimestamp, modifyApp, modifyLogin,
modifyTimestamp, recordStatus, sessionId) VALUES (?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?) [params=(long) 904, (double) 0.0, (double)
400.0, (int) 1, (long) 901, (long) 104, (null) null, (String)
TestClient, (String) test, (Timestamp) 2009-02-13 13:54:12.364,
(String) TestClient, (String) test, (Timestamp) 2009-02-13
13:54:12.364, (String) A, (String) ABC]
341703  QERP_EJB  TRACE  [ejbd 11] openjpa.jdbc.SQL - <t 19397104,
conn 32165850> [0 ms] spent



< below are unnecessary UPDATE statement >

UPDATE ProductionOrder SET version = ?, createApp = ?, createLogin =
?, createTimestamp = ?, modifyApp = ?, modifyLogin = ?,
modifyTimestamp = ?, recordStatus = ?, sessionId = ? WHERE
id_ProductionOrder = ? AND version = ? [params=(int) 2, (String)
TestClient, (String) test, (Timestamp) 2009-02-13 13:54:12.319,
(String) TestClient, (String) test, (Timestamp) 2009-02-13
13:54:12.365, (String) A, (String) , (long) 900, (int) 1]

UPDATE ProductionOrderMaterial SET version = ?, createApp = ?,
createLogin = ?, createTimestamp = ?, modifyApp = ?, modifyLogin = ?,
modifyTimestamp = ?, recordStatus = ?, sessionId = ? WHERE
id_ProductionOrderMaterial = ? AND version = ? [params=(int) 2,
(String) TestClient, (String) test, (Timestamp) 2009-02-13
13:54:12.32, (String) TestClient, (String) test, (Timestamp)
2009-02-13 13:54:12.365, (String) A, (String) ABC, (long) 901, (int)
2]

UPDATE ProductionOrderMaterial SET version = ?, createApp = ?,
createLogin = ?, createTimestamp = ?, modifyApp = ?, modifyLogin = ?,
modifyTimestamp = ?, recordStatus = ?, sessionId = ? WHERE
id_ProductionOrderMaterial = ? AND version = ? [params=(int) 2,
(String) TestClient, (String) test, (Timestamp) 2009-02-13
13:54:12.32, (String) TestClient, (String) test, (Timestamp)
2009-02-13 13:54:12.365, (String) A, (String) ABC, (long) 900, (int)
2]




Below are classes for reference

public class ProductionOrder extends BaseEntity
{

	@OneToMany(cascade=
{CascadeType.PERSIST,CascadeType.REFRESH,CascadeType.REMOVE}, fetch =
FetchType.EAGER, mappedBy="productionOrder",
targetEntity=ProductionOrderMaterial.class)
	private List<ProductionOrderMaterial> productionOrderMaterials;

	@PrePersist
	void prePersist() throws BusinessException {
		validate();
		
		rowInfo.setRecordStatus("A");
		
	    java.util.Date today = new java.util.Date();

	    rowInfo.setModifyTimestamp(new java.sql.Timestamp(today.getTime()));
	    rowInfo.setCreateTimestamp(rowInfo.getModifyTimestamp());			
		System.out.println("[PrePersist] " + rowInfo.getCreateLogin());
	}


	@PreUpdate
	void preUpdate() throws BusinessException {
		if(rowInfo.getRecordStatus()!="D")
		{
			validate();
		}
			java.util.Date today = new java.util.Date();

			rowInfo.setModifyTimestamp(new java.sql.Timestamp(today.getTime()));
		
		
	}

public class ProductionOrderMaterial extends BaseEntity
{

	@ManyToOne
       @JoinColumn(name="fk_ProductionOrder")	
	private ProductionOrder productionOrder;



	@PrePersist
	void prePersist() throws BusinessException {
		validate();
		
		rowInfo.setRecordStatus("A");
		
	    java.util.Date today = new java.util.Date();

	    rowInfo.setModifyTimestamp(new java.sql.Timestamp(today.getTime()));
	    rowInfo.setCreateTimestamp(rowInfo.getModifyTimestamp());			
				
	}


	@PreUpdate
	void preUpdate() throws BusinessException {
		if(rowInfo.getRecordStatus()!="D")
		{
			validate();
		}
			java.util.Date today = new java.util.Date();

			rowInfo.setModifyTimestamp(new java.sql.Timestamp(today.getTime()));
		
		
	}







}

Mime
View raw message