openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fayw...@apache.org
Subject svn commit: r995333 - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ openjpa-kernel/src/main/java/org/apache/openjpa/util/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/
Date Thu, 09 Sep 2010 06:47:46 GMT
Author: faywang
Date: Thu Sep  9 06:47:46 2010
New Revision: 995333

URL: http://svn.apache.org/viewvc?rev=995333&view=rev
Log:
OPENJPA-1784: improve dirty-checking for persistent maps when the get method is called to
retrieve an embeddable value.

Added:
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/LocalizedString.java
  (with props)
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/MultilingualString.java
  (with props)
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/TestMapUpdate.java
  (with props)
Modified:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerHandlerMapTableFieldStrategy.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyMaps.java

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerHandlerMapTableFieldStrategy.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerHandlerMapTableFieldStrategy.java?rev=995333&r1=995332&r2=995333&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerHandlerMapTableFieldStrategy.java
(original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerHandlerMapTableFieldStrategy.java
Thu Sep  9 06:47:46 2010
@@ -21,6 +21,7 @@ package org.apache.openjpa.jdbc.meta.str
 import java.sql.*;
 import java.util.*;
 
+import org.apache.openjpa.enhance.PersistenceCapable;
 import org.apache.openjpa.jdbc.identifier.DBIdentifier;
 import org.apache.openjpa.jdbc.kernel.*;
 import org.apache.openjpa.jdbc.meta.*;
@@ -214,8 +215,11 @@ public class HandlerHandlerMapTableField
 
             for (Iterator itr = change.iterator(); itr.hasNext();) {
                 mkey = itr.next();
+                Object mval = map.get(mkey);
+                if ((mval instanceof PersistenceCapable) && !((PersistenceCapable)mval).pcIsDirty())
+                    continue;   
                 HandlerStrategies.where(key, mkey, store, changeRow, _kcols);
-                HandlerStrategies.set(val, map.get(mkey), store, changeRow,
+                HandlerStrategies.set(val, mval, store, changeRow,
                     _vcols, _vio, true);
                 rm.flushSecondaryRow(changeRow);
             }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyMaps.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyMaps.java?rev=995333&r1=995332&r2=995333&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyMaps.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyMaps.java Thu
Sep  9 06:47:46 2010
@@ -23,10 +23,11 @@ import java.io.ObjectStreamException;
 import java.util.AbstractSet;
 import java.util.Collection;
 import java.util.Map;
-import java.util.Comparator;
 import java.util.Iterator;
 import java.util.Set;
 
+import org.apache.openjpa.enhance.PersistenceCapable;
+
 /**
  * Utility methods used by map proxies.
  *
@@ -75,6 +76,32 @@ public class ProxyMaps 
     }
 
     /**
+     * Call before invoking {@link Map#get} on super.
+     */
+    public static boolean beforeGet(ProxyMap map, Object key) {
+        assertAllowedType(key, map.getKeyType());
+        return map.containsKey(key);
+    }
+
+    /**
+     * Call after invoking {@link Map#get} on super.
+     *
+     * @param ret the return value from the super's method
+     * @param before the return value from {@link #beforeGet}
+     * @return the value to return from {@link Map#get}
+     */
+    public static Object afterGet(ProxyMap map, Object key,
+        Object ret, boolean before) {
+        if (before) {
+            if (map.getChangeTracker() != null && (ret instanceof PersistenceCapable))
+                ((MapChangeTracker) map.getChangeTracker()).changed(key, ret, 
+                    ret);
+        } 
+        return ret;
+    }
+
+
+    /**
      * Call before invoking {@link Map#put} on super.
      */
     public static boolean beforePut(ProxyMap map, Object key, Object value) {

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/LocalizedString.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/LocalizedString.java?rev=995333&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/LocalizedString.java
(added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/LocalizedString.java
Thu Sep  9 06:47:46 2010
@@ -0,0 +1,87 @@
+package org.apache.openjpa.persistence.jdbc.maps.update;
+
+import java.io.Serializable;
+
+import javax.persistence.Embeddable;
+
+/**
+ * A LocalizedString is any text string combined with a language code. The
+ * language codes are two lower-case characters according to ISO-639-1, e.g.
+ * "de" = German, "en" = English.
+ * 
+ * The language may be null for strings like phone numbers.
+ * 
+ * @author Harald Wellmann
+ * 
+ */
+@Embeddable
+public class LocalizedString implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** Language code. */
+    private String language;
+
+    private String string;
+
+    public LocalizedString() {
+    }
+
+    public LocalizedString(String language, String text) {
+        this.language = language;
+        this.string = text;
+    }
+
+    public String getLanguage() {
+        return language;
+    }
+
+    public void setLanguage(String language) {
+        this.language = language;
+    }
+
+    public String getString() {
+        return string;
+    }
+
+    public void setString(String text) {
+        this.string = text;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result
+                + ((language == null) ? 0 : language.hashCode());
+        result = prime * result + ((string == null) ? 0 : string.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        LocalizedString other = (LocalizedString) obj;
+        if (language == null) {
+            if (other.language != null)
+                return false;
+        } else if (!language.equals(other.language))
+            return false;
+        if (string == null) {
+            if (other.string != null)
+                return false;
+        } else if (!string.equals(other.string))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return string;
+    }
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/LocalizedString.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/MultilingualString.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/MultilingualString.java?rev=995333&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/MultilingualString.java
(added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/MultilingualString.java
Thu Sep  9 06:47:46 2010
@@ -0,0 +1,67 @@
+package org.apache.openjpa.persistence.jdbc.maps.update;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.ElementCollection;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.MapKeyColumn;
+import javax.persistence.Table;
+
+
+@Entity
+@Table(name = "multilingual_string")
+public class MultilingualString {
+
+    private static final long serialVersionUID = 1L;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE)
+    @Column(name = "string_id")
+    private long id;
+
+    @ElementCollection(fetch=FetchType.EAGER)
+    @MapKeyColumn(name = "language_key")
+    @CollectionTable(name = "multilingual_string_map", joinColumns = @JoinColumn(name = "string_id"))
+    private Map<String, LocalizedString> map = new HashMap<String, LocalizedString>();
+
+    public MultilingualString() {}
+    
+    public MultilingualString(String lang, String text) {
+        setText(lang, text);
+    }
+    
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public Map<String, LocalizedString> getMap() {
+        return map;
+    }
+
+    public void setMap(Map<String, LocalizedString> map) {
+        this.map = map;
+    }
+
+    public void setText(String lang, String text) {
+        map.put(lang, new LocalizedString(lang, text));
+    }
+
+    public String getText(String lang) {
+        if (map.containsKey(lang)) {
+            return map.get(lang).getString();
+        }
+        return null;
+    }
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/MultilingualString.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/TestMapUpdate.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/TestMapUpdate.java?rev=995333&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/TestMapUpdate.java
(added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/TestMapUpdate.java
Thu Sep  9 06:47:46 2010
@@ -0,0 +1,98 @@
+/*
+ * 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.jdbc.maps.update;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.test.SQLListenerTestCase;
+
+/**
+ * 
+ * @author Harald Wellmann
+ *
+ */
+public class TestMapUpdate extends SQLListenerTestCase {
+
+    private MultilingualString entity1;
+	private OpenJPAEntityManagerSPI em;
+
+	public void setUp() {
+        super.setUp(CLEAR_TABLES,
+            MultilingualString.class,
+            LocalizedString.class);
+        createObj(emf);
+        em = emf.createEntityManager();
+    }
+
+    public void testUpdateMapKey() throws Exception {
+    	em.getTransaction().begin();
+    	
+    	MultilingualString ms = em.find(MultilingualString.class, entity1.getId());
+    	assertNotNull(ms);
+    
+    	// Overwrite an existing map entry.
+    	// The key is now dirty, and OpenJPA will generate an SQL UPDATE.
+    	ms.setText("en", "Good evening");    	
+    	em.getTransaction().commit();
+    	em.clear();
+    	
+    	em.getTransaction().begin();
+    	ms = em.find(MultilingualString.class, entity1.getId());
+    	assertEquals("Good evening", ms.getText("en"));
+    	em.getTransaction().commit();
+    }
+    
+    public void testUpdateMapValue() throws Exception {
+    	em.getTransaction().begin();
+    	
+    	MultilingualString ms = em.find(MultilingualString.class, entity1.getId());
+    	assertNotNull(ms);
+    	
+    	// Change an existing map value. This makes the map dirty,
+    	// but OpenJPA does not recognize it. No SQL UPDATE is generated.
+    	ms.getMap().get("en").setString("Good evening");
+    	em.getTransaction().commit();
+    	em.clear();
+    	
+    	em.getTransaction().begin();
+    	ms = em.find(MultilingualString.class, entity1.getId());
+    	
+    	// This assertion fails, the entity still has the old value.
+    	assertEquals("Good evening", ms.getText("en"));
+    	em.getTransaction().commit();
+    }
+    
+    private void createObj(EntityManagerFactory emf) {
+        EntityManager em = emf.createEntityManager();
+        EntityTransaction tran = em.getTransaction();
+        tran.begin();
+        
+        entity1 = new MultilingualString("de", "Guten Tag");
+        entity1.setText("en", "Good morning");
+        em.persist(entity1);
+        
+        em.flush();
+        tran.commit();
+        em.close();
+    }
+}
+

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/maps/update/TestMapUpdate.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message