You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by ht...@apache.org on 2011/02/11 21:58:14 UTC

svn commit: r1069955 - in /openjpa/branches/1.3.x: openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/

Author: hthomann
Date: Fri Feb 11 20:58:13 2011
New Revision: 1069955

URL: http://svn.apache.org/viewvc?rev=1069955&view=rev
Log:
OPENJPA-1911: fix merge problem for entities with derived id - merged this code from Fay's changes for trunk

Added:
    openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/
    openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchy.java   (with props)
    openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchyRate.java   (with props)
    openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchyRateOpenJPAKey.java   (with props)
    openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/TestMergeComplexKey.java   (with props)
Modified:
    openjpa/branches/1.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java

Modified: openjpa/branches/1.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?rev=1069955&r1=1069954&r2=1069955&view=diff
==============================================================================
--- openjpa/branches/1.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java (original)
+++ openjpa/branches/1.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java Fri Feb 11 20:58:13 2011
@@ -1876,9 +1876,25 @@ public class StateManagerImpl
                     case JavaTypes.ARRAY:
                     case JavaTypes.COLLECTION:
                     case JavaTypes.MAP:
-                    case JavaTypes.PC:
                     case JavaTypes.PC_UNTYPED:
                         break;
+                    case JavaTypes.PC:
+                        if (_meta.getField(field).isPrimaryKey()) {
+                            // this field is a derived identity
+                            //if (newVal != null && newVal.equals(curVal))
+                            //    return;
+                            //else {
+                                if (curVal != null && newVal != null && 
+                                    curVal instanceof PersistenceCapable && newVal instanceof PersistenceCapable) {
+                                    PersistenceCapable curPc = (PersistenceCapable) curVal;
+                                    PersistenceCapable newPc = (PersistenceCapable) newVal;
+                                    if (curPc.pcFetchObjectId().equals(newPc.pcFetchObjectId()))
+                                        return;
+                                    
+                                }
+                            //}
+                        } else     
+                            break;
                     default:
                         if (newVal != null && newVal.equals(curVal))
                             return;

Added: openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchy.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchy.java?rev=1069955&view=auto
==============================================================================
--- openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchy.java (added)
+++ openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchy.java Fri Feb 11 20:58:13 2011
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.xs;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+@Entity
+@Table(name = "PM_ACCOUNTING_HIERARCHY_TEST")
+public class AccountingHierarchy implements Serializable {
+
+    private static final long serialVersionUID = -1759978020595211326L;
+
+    private String code;
+    private String shortDesc;
+
+    private List<AccountingHierarchyRate> accRateList = new ArrayList<AccountingHierarchyRate>(0);
+
+    private Long version;
+
+    public AccountingHierarchy() {
+    }
+
+    public AccountingHierarchy(String code) {
+        this.code = code;
+    }
+
+    public AccountingHierarchy(String code, String shortDesc) {
+        this.code = code;
+        this.shortDesc = shortDesc;
+    }
+
+    public AccountingHierarchy(String code, String shortDesc, String hierarchyType) {
+        this.code = code;
+        this.shortDesc = shortDesc;
+    }
+
+    @Id
+    @Column(name = "code", length = 20)
+    public String getCode() {
+        return code;
+    }
+
+    @Column(name = "short_desc", nullable = false, length = 50)
+    public String getShortDesc() {
+        return shortDesc;
+    }
+
+    @OneToMany(mappedBy = "accountingHierarchy", fetch = FetchType.EAGER, 
+        targetEntity = AccountingHierarchyRate.class, cascade = CascadeType.ALL)
+    public List<AccountingHierarchyRate> getAccRateList() {
+        return accRateList;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public void setShortDesc(String shortDesc) {
+        this.shortDesc = shortDesc;
+    }
+
+    public void setAccRateList(List<AccountingHierarchyRate> accRateList) {
+        this.accRateList = accRateList;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((getCode() == null) ? 0 : getCode().hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (!(obj instanceof AccountingHierarchy))
+            return false;
+        AccountingHierarchy other = (AccountingHierarchy) obj;
+        if (getCode() == null) {
+            if (other.getCode() != null)
+                return false;
+        } else if (!getCode().equals(other.getCode()))
+            return false;
+        return true;
+    }
+
+    @Transient
+    public Long getVersion() {
+        return version;
+    }
+
+    public void setVersion(Long version) {
+        this.version = version;
+    }
+
+    @Override
+    public String toString() {
+        return "AccountingHierarchy [getCode()=" + getCode() + ", getShortDesc()=" + getShortDesc() + "]";
+    }
+
+}

Propchange: openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchyRate.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchyRate.java?rev=1069955&view=auto
==============================================================================
--- openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchyRate.java (added)
+++ openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchyRate.java Fri Feb 11 20:58:13 2011
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.xs;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "PM_ACCOUNTING_HIERARCHY_RATE_TEST")
+@IdClass(AccountingHierarchyRateOpenJPAKey.class)
+public class AccountingHierarchyRate implements Serializable {
+
+	private static final long serialVersionUID = 538926265319989492L;
+
+	private String id;
+	private AccountingHierarchy accountingHierarchy;
+
+	private BigDecimal currentRate;
+	private BigDecimal budgetRate;
+
+	public AccountingHierarchyRate() {
+	}
+
+	public AccountingHierarchyRate(String id, AccountingHierarchy accountingHierarchy, 
+	        BigDecimal currentRate, BigDecimal budgetRate) {
+		this.id = id;
+		this.accountingHierarchy = accountingHierarchy;
+		this.currentRate = currentRate;
+		this.budgetRate = budgetRate;
+	}
+
+	@Id
+	@Column(name = "id", length = 20, nullable = false)
+	public String getId() {
+		return id;
+	}
+
+	@Id
+	@ManyToOne(targetEntity = AccountingHierarchy.class, fetch = FetchType.LAZY)
+	@JoinColumn(name = "acc_hier", nullable = false)
+	public AccountingHierarchy getAccountingHierarchy() {
+		return accountingHierarchy;
+	}
+
+	@Column(name = "current_rate", nullable = true, precision = 12, scale = 4)
+	public BigDecimal getCurrentRate() {
+		return currentRate;
+	}
+
+	@Column(name = "budget_rate", nullable = true, precision = 12, scale = 4)
+	public BigDecimal getBudgetRate() {
+		return budgetRate;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public void setAccountingHierarchy(AccountingHierarchy accountingHierarchy) {
+		this.accountingHierarchy = accountingHierarchy;
+	}
+
+	public void setCurrentRate(BigDecimal currentRate) {
+		this.currentRate = currentRate;
+	}
+
+	public void setBudgetRate(BigDecimal budgetRate) {
+		this.budgetRate = budgetRate;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
+		result = prime * result + ((getAccountingHierarchy() == null) ? 0 : 
+		    getAccountingHierarchy().hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (!(obj instanceof AccountingHierarchyRate))
+			return false;
+		AccountingHierarchyRate other = (AccountingHierarchyRate) obj;
+		if (getId() == null) {
+			if (other.getId() != null)
+				return false;
+		} else if (!getId().equals(other.getId()))
+			return false;
+		if (getAccountingHierarchy() == null) {
+			if (other.getAccountingHierarchy() != null)
+				return false;
+		} else if (!getAccountingHierarchy().equals(other.getAccountingHierarchy()))
+			return false;
+		return true;
+	}
+}

Propchange: openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchyRate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchyRateOpenJPAKey.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchyRateOpenJPAKey.java?rev=1069955&view=auto
==============================================================================
--- openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchyRateOpenJPAKey.java (added)
+++ openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchyRateOpenJPAKey.java Fri Feb 11 20:58:13 2011
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.xs;
+
+import java.io.Serializable;
+
+/**
+ *
+ * Auto-generated by:
+ * org.apache.openjpa.enhance.ApplicationIdTool
+ */
+public class AccountingHierarchyRateOpenJPAKey implements Serializable {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -2345673847908844341L;
+
+	static {
+		// register persistent class in JVM
+		try { Class.forName("org.apache.openjpa.persistence.xs.AccountingHierarchyRate"); }
+		catch(Exception e) {}
+	}
+
+	public String accountingHierarchy;
+	public String id;
+
+	public AccountingHierarchyRateOpenJPAKey() {
+	}
+
+	public AccountingHierarchyRateOpenJPAKey(String str) {
+		fromString(str);
+	}
+
+	public String getAccountingHierarchy() {
+		return accountingHierarchy;
+	}
+
+	public void setAccountingHierarchy(String accountingHierarchy) {
+		this.accountingHierarchy = accountingHierarchy;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String toString() {
+		return accountingHierarchy
+			+ "::" + id;
+	}
+
+	public int hashCode() {
+		int rs = 17;
+		rs = rs * 37 + ((accountingHierarchy == null) ? 0 : accountingHierarchy.hashCode());
+		rs = rs * 37 + ((id == null) ? 0 : id.hashCode());
+		return rs;
+	}
+
+	public boolean equals(Object obj) {
+		if(this == obj)
+			return true;
+		if(obj == null || obj.getClass() != getClass())
+			return false;
+
+		AccountingHierarchyRateOpenJPAKey other = (AccountingHierarchyRateOpenJPAKey) obj;
+		return ((accountingHierarchy == null && other.accountingHierarchy == null)
+			|| (accountingHierarchy != null && accountingHierarchy.equals(other.accountingHierarchy)))
+			&& ((id == null && other.id == null)
+			|| (id != null && id.equals(other.id)));
+	}
+
+	private void fromString(String str) {
+		Tokenizer toke = new Tokenizer(str);
+		str = toke.nextToken();
+		if("null".equals(str))
+			accountingHierarchy = null;
+		else
+			accountingHierarchy = str;
+		str = toke.nextToken();
+		if("null".equals(str))
+			id = null;
+		else
+			id = str;
+	}
+
+	protected static class Tokenizer {
+		private final String str;
+		private int last;
+
+		public Tokenizer (String str) {
+			this.str = str;
+		}
+
+		public String nextToken () {
+			int next = str.indexOf("::", last);
+			String part;
+			if(next == -1) {
+				part = str.substring(last);
+				last = str.length();
+			} else {
+				part = str.substring(last, next);
+				last = next + 2;
+			}
+			return part;
+		}
+	}
+}

Propchange: openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/AccountingHierarchyRateOpenJPAKey.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/TestMergeComplexKey.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/TestMergeComplexKey.java?rev=1069955&view=auto
==============================================================================
--- openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/TestMergeComplexKey.java (added)
+++ openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/TestMergeComplexKey.java Fri Feb 11 20:58:13 2011
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.xs;
+
+import java.math.BigDecimal;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestMergeComplexKey extends SingleEMFTestCase {
+    Object[] props = new Object[] { AccountingHierarchy.class, AccountingHierarchyRate.class, CLEAR_TABLES };
+
+    @Override
+    public void setUp() throws Exception {
+        setUp(props);
+    }
+
+    public void test() throws Exception {
+        createDate();
+        EntityManager em = emf.createEntityManager();
+        AccountingHierarchy accountingHierarchy = (AccountingHierarchy) em.find(AccountingHierarchy.class, "TESTING");
+        accountingHierarchy.setShortDesc("NAME:" + System.currentTimeMillis());
+        accountingHierarchy = (AccountingHierarchy) AbstractTestCase.roundtrip(accountingHierarchy,false);
+        em.close();
+
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        try {
+            em.merge(accountingHierarchy);
+        } catch (RuntimeException e) {
+            em.getTransaction().setRollbackOnly();
+            throw e;
+        } finally {
+            if (em.getTransaction().getRollbackOnly()) {
+                em.getTransaction().rollback();
+            } else {
+                em.getTransaction().commit();
+            }
+        }
+
+    }
+
+    void createDate() {
+        EntityManager em = emf.createEntityManager();
+        System.out.println(em.createQuery("select o from AccountingHierarchy o").getResultList().size());
+
+        String code = "TESTING";
+        AccountingHierarchy accountingHierarchy = em.find(AccountingHierarchy.class, code);
+        if (accountingHierarchy == null) {
+            accountingHierarchy = new AccountingHierarchy();
+            accountingHierarchy.setCode(code);
+            accountingHierarchy.setShortDesc("TESTING");
+
+            AccountingHierarchyRate accountingHierarchyRate =
+                new AccountingHierarchyRate("1", accountingHierarchy, BigDecimal.ONE, BigDecimal.TEN);
+
+            accountingHierarchy.getAccRateList().add(accountingHierarchyRate);
+
+            EntityTransaction tx = em.getTransaction();
+            tx.begin();
+            try {
+                em.persist(accountingHierarchy);
+            } catch (RuntimeException e) {
+                tx.setRollbackOnly();
+                throw e;
+            } finally {
+                if (tx.getRollbackOnly()) {
+                    tx.rollback();
+                } else {
+                    tx.commit();
+                }
+            }
+        }
+
+    }
+}

Propchange: openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xs/TestMergeComplexKey.java
------------------------------------------------------------------------------
    svn:eol-style = native