Author: mikedd
Date: Wed Jul  6 18:17:36 2011
New Revision: 1143519

URL: http://svn.apache.org/viewvc?rev=1143519&view=rev
Log:
OPENJPA-2027: Use SingularAttribute for unannotated arrays. ListAttribute for 
@PersistentCollections

Added:
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/BlogUser.java
   (with props)
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/BlogUser_.java
   (with props)
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestByteArray.java
   (with props)
Modified:
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AbstractManagedType.java
    openjpa/trunk/openjpa-project/src/doc/manual/migration_considerations.xml

Modified: 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java?rev=1143519&r1=1143518&r2=1143519&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
 Wed Jul  6 18:17:36 2011
@@ -69,7 +69,9 @@ public class Compatibility {
     private boolean _checkDatabaseForCascadePersistToDetachedEntity = false;
     private boolean _overrideContextClassloader = true;
     private boolean _parseAnnotationsForQueryMode = true;
-    private boolean _convertPositionalParametersToNamed = false;    
+    private boolean _convertPositionalParametersToNamed = false;
+    
+    private boolean _useListAttributeForArrays = false; 
     
     /**
      * Whether to require exact identity value types when creating object
@@ -608,4 +610,34 @@ public class Compatibility {
     public void setParseAnnotationsForQueryMode(boolean 
parseAnnotationsForQueryMode) {
         _parseAnnotationsForQueryMode = parseAnnotationsForQueryMode;
     }
+
+    /**
+     * This property can be used to allow OpenJPA to use ListAttributes for 
all types of Arrays, not just those with the
+     * 
+     * @PersistentCollection annotation. If the canonical metamodel classes 
were generated in an early version of
+     *                       OpenJPA (e.g. 2.0.0, 2.0.1, or 2.1.0) it is 
recommended to set this property to true. If
+     *                       you have generated your metamodel classes on 
later versions of OpenJPA (e.g. 2.2.0) you may
+     *                       want to have this set to false.
+     * @since 2.2.0
+     * @return true if OpenJPA will use ListAttributes for <b>all</b> arrays, 
false if OpenJPA will use ListAttributes
+     *         for <b>only</b> arrays which use the @PersistentCollection 
annotation.
+     */
+    public boolean getUseListAttributeForArrays() {
+        return _useListAttributeForArrays;
+    }
+
+    /**
+     * This property can be used to allow OpenJPA to use ListAttributes for 
all types of Arrays, not just those with the
+     * 
+     * @PersistentCollection annotation. If the canonical metamodel classes 
were generated in an early version of
+     *                       OpenJPA (e.g. 2.0.0, 2.0.1, or 2.1.0) it is 
recommended to set this property to true. If
+     *                       you have generated your metamodel classes on 
later versions of OpenJPA (e.g. 2.2.0) you may
+     *                       want to have this set to false.
+     * @since 2.2.0
+     * @param useListAttribute
+     *            whether OpenJPA will use ListAttributes for all arrays.
+     */   
+    public void setUseListAttributeForArrays(boolean useListAttribute ) { 
+        _useListAttributeForArrays = useListAttribute;
+    }
 }

Modified: 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java?rev=1143519&r1=1143518&r2=1143519&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
 Wed Jul  6 18:17:36 2011
@@ -220,6 +220,8 @@ public class FieldMetaData
     private boolean _isElementCollection = false;
     private int _associationType;
 
+    private boolean _persistentCollection = false; 
+
     /**
      * Constructor.
      *
@@ -2380,5 +2382,13 @@ public class FieldMetaData
     public void setAssociationType(int type) {
         _associationType = type;
     }
+
+    public boolean isPersistentCollection() {
+        return _persistentCollection;
+    }
+
+    public void setPersistentCollection(boolean persistentCollection) {
+        _persistentCollection = persistentCollection;
+    }
     
 }

Added: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/BlogUser.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/BlogUser.java?rev=1143519&view=auto
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/BlogUser.java
 (added)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/BlogUser.java
 Wed Jul  6 18:17:36 2011
@@ -0,0 +1,88 @@
+/*
+ * 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.criteria;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+@Entity
+public class BlogUser {
+    @Id
+    @GeneratedValue
+    private int id;
+
+    @Version
+    private int version;
+
+    private String username;
+    private byte[] pic;
+    private Character [] characters; 
+    private char [] chars; 
+
+    public char[] getChars() {
+        return chars;
+    }
+
+    public void setChars(char[] littleChars) {
+        this.chars = littleChars;
+    }
+
+    public Character[] getCharacters() {
+        return characters;
+    }
+
+    public void setCharacters(Character[] chars) {
+        this.characters = chars;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public int getVersion() {
+        return version;
+    }
+
+    public void setVersion(int version) {
+        this.version = version;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public byte[] getPic() {
+        return pic;
+    }
+
+    public void setPic(byte[] pic) {
+        this.pic = pic;
+    }
+}

Propchange: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/BlogUser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/BlogUser_.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/BlogUser_.java?rev=1143519&view=auto
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/BlogUser_.java
 (added)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/BlogUser_.java
 Wed Jul  6 18:17:36 2011
@@ -0,0 +1,38 @@
+/*
+ * 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.    
+ */
+/** 
+ *  Generated by OpenJPA MetaModel Generator Tool.
+**/
+
+package org.apache.openjpa.persistence.criteria;
+
+import javax.persistence.metamodel.SingularAttribute;
+
[email protected]
+(value=org.apache.openjpa.persistence.criteria.BlogUser.class)
[email protected]
+(value="org.apache.openjpa.persistence.meta.AnnotationProcessor6",date="Wed 
Jul 06 09:09:40 CDT 2011")
+public class BlogUser_ {
+    public static volatile SingularAttribute<BlogUser,Character[]> characters;
+    public static volatile SingularAttribute<BlogUser,char[]> chars;
+    public static volatile SingularAttribute<BlogUser,Integer> id;
+    public static volatile SingularAttribute<BlogUser,byte[]> pic;
+    public static volatile SingularAttribute<BlogUser,String> username;
+    public static volatile SingularAttribute<BlogUser,Integer> version;
+}

Propchange: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/BlogUser_.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestByteArray.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestByteArray.java?rev=1143519&view=auto
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestByteArray.java
 (added)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestByteArray.java
 Wed Jul  6 18:17:36 2011
@@ -0,0 +1,175 @@
+/*
+ * 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.criteria;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Root;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestByteArray extends SingleEMFTestCase {
+    protected CriteriaBuilder cb;
+    String pic = "IamNotAPicture";
+    Character[] chars = new Character[] { new Character('a'), new 
Character('b') };
+    public void setUp() {
+        super.setUp(BlogUser.class
+//            ,"openjpa.Compatibility", "UseListAttributeForArrays=false"
+            );
+        cb = emf.getCriteriaBuilder();
+        populate();
+    }
+
+    public void populate() {
+        EntityManager em = emf.createEntityManager();
+        EntityTransaction tran = em.getTransaction();
+        tran.begin();
+
+        BlogUser bu = new BlogUser();
+        bu.setUsername("jode1");
+        bu.setPic(pic.getBytes());
+        bu.setCharacters(chars);
+        bu.setChars(pic.toCharArray());
+
+        em.persist(bu);
+        tran.commit();
+
+        em.close();
+    }
+
+    public void assertBlogUser(BlogUser bu) {
+        assertNotNull(bu);
+        assertNotNull(bu.getPic());
+        assertNotNull(bu.getCharacters());
+        assertNotNull(bu.getChars());
+    }
+
+    public void testSimpleQuery() {
+        EntityManager em = emf.createEntityManager();
+        CriteriaQuery<BlogUser> cq = cb.createQuery(BlogUser.class);
+        cq.select(cq.from(BlogUser.class));
+
+        List<BlogUser> users = em.createQuery(cq).getResultList();
+
+        assertNotNull(users);
+        assertFalse(users.isEmpty());
+
+        assertBlogUser(users.get(0));
+
+        em.close();
+    }
+
+    public void testSimpleQueryBytesNotNull() {
+        EntityManager em = emf.createEntityManager();
+        CriteriaQuery<BlogUser> cq = cb.createQuery(BlogUser.class);
+        Root<BlogUser> bloguser = cq.from(BlogUser.class);
+        cq.select(bloguser);
+        cq.where(bloguser.get(BlogUser_.pic).isNotNull());
+
+        List<BlogUser> users = em.createQuery(cq).getResultList();
+
+        assertNotNull(users);
+        assertFalse(users.isEmpty());
+        assertBlogUser(users.get(0));
+
+        em.close();
+    }     
+    
+    public void testSimpleQueryBytesNull() {
+        EntityManager em = emf.createEntityManager();
+        CriteriaQuery<BlogUser> cq = cb.createQuery(BlogUser.class);
+        Root<BlogUser> bloguser = cq.from(BlogUser.class);
+        cq.select(bloguser);
+        cq.where(bloguser.get(BlogUser_.pic).isNull());
+
+        List<BlogUser> users = em.createQuery(cq).getResultList();
+
+        assertNotNull(users);
+        assertTrue(users.isEmpty());
+
+        em.close();
+    }
+
+    public void testSimpleQueryCharactersNotNull() {
+        EntityManager em = emf.createEntityManager();
+        CriteriaQuery<BlogUser> cq = cb.createQuery(BlogUser.class);
+        Root<BlogUser> bloguser = cq.from(BlogUser.class);
+        cq.select(bloguser);
+        cq.where(bloguser.get(BlogUser_.characters).isNotNull());
+
+        List<BlogUser> users = em.createQuery(cq).getResultList();
+
+        assertNotNull(users);
+        assertFalse(users.isEmpty());
+        assertBlogUser(users.get(0));
+
+        em.close();
+    }
+    public void testSimpleQueryCharactersNull() {
+        EntityManager em = emf.createEntityManager();
+        CriteriaQuery<BlogUser> cq = cb.createQuery(BlogUser.class);
+        Root<BlogUser> bloguser = cq.from(BlogUser.class);
+        cq.select(bloguser);
+        cq.where(bloguser.get(BlogUser_.characters).isNull());
+
+        List<BlogUser> users = em.createQuery(cq).getResultList();
+
+        assertNotNull(users);
+        assertTrue(users.isEmpty());
+
+        em.close();
+    }
+
+    public void testSimpleQueryCharsNotNull() {
+        EntityManager em = emf.createEntityManager();
+        CriteriaQuery<BlogUser> cq = cb.createQuery(BlogUser.class);
+        Root<BlogUser> bloguser = cq.from(BlogUser.class);
+        cq.select(bloguser);
+        cq.where(bloguser.get(BlogUser_.chars).isNotNull());
+
+        List<BlogUser> users = em.createQuery(cq).getResultList();
+
+        assertNotNull(users);
+        assertFalse(users.isEmpty());
+        assertBlogUser(users.get(0));
+
+        em.close();
+    }
+    
+    public void testSimpleQueryCharsNull() {
+        EntityManager em = emf.createEntityManager();
+        CriteriaQuery<BlogUser> cq = cb.createQuery(BlogUser.class);
+        Root<BlogUser> bloguser = cq.from(BlogUser.class);
+        cq.select(bloguser);
+        cq.where(bloguser.get(BlogUser_.chars).isNull());
+
+        List<BlogUser> users = em.createQuery(cq).getResultList();
+
+        assertNotNull(users);
+        assertTrue(users.isEmpty());
+
+        em.close();
+    }
+
+}

Propchange: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestByteArray.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java?rev=1143519&r1=1143518&r2=1143519&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
 Wed Jul  6 18:17:36 2011
@@ -1634,6 +1634,8 @@ public class AnnotationPersistenceMetaDa
             throw new MetaDataException(_loc.get("bad-meta-anno", fmd,
                 "PersistentCollection"));
 
+        fmd.setPersistentCollection(true); 
+        
         if (!StringUtils.isEmpty(anno.mappedBy()))
             fmd.setMappedBy(anno.mappedBy());
         fmd.setInDefaultFetchGroup(anno.fetch() == FetchType.EAGER);

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AbstractManagedType.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AbstractManagedType.java?rev=1143519&r1=1143518&r2=1143519&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AbstractManagedType.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AbstractManagedType.java
 Wed Jul  6 18:17:36 2011
@@ -39,6 +39,7 @@ import javax.persistence.metamodel.SetAt
 import javax.persistence.metamodel.SingularAttribute;
 import javax.persistence.metamodel.PluralAttribute.CollectionType;
 
+import org.apache.openjpa.conf.Compatibility;
 import org.apache.openjpa.kernel.Filters;
 import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.meta.ClassMetaData;
@@ -157,7 +158,13 @@ public abstract class AbstractManagedTyp
                 attrs.add(new Members.SingularAttributeImpl(this, f));
                 break;
             case JavaTypes.ARRAY:
-                attrs.add(new Members.ListAttributeImpl(this, f));
+                Compatibility compat = 
meta.getRepository().getConfiguration().getCompatibilityInstance();
+                if(compat.getUseListAttributeForArrays() || 
f.isPersistentCollection()) {
+                    attrs.add(new Members.ListAttributeImpl(this, f));
+                }
+                else { 
+                    attrs.add(new Members.SingularAttributeImpl(this, f));
+                }
                 break;
             case JavaTypes.COLLECTION:
                 switch 
(MetamodelImpl.categorizeCollection(f.getDeclaredType())) {

Modified: 
openjpa/trunk/openjpa-project/src/doc/manual/migration_considerations.xml
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-project/src/doc/manual/migration_considerations.xml?rev=1143519&r1=1143518&r2=1143519&view=diff
==============================================================================
--- openjpa/trunk/openjpa-project/src/doc/manual/migration_considerations.xml 
(original)
+++ openjpa/trunk/openjpa-project/src/doc/manual/migration_considerations.xml 
Wed Jul  6 18:17:36 2011
@@ -406,6 +406,33 @@
                     </itemizedlist>
                 </para>
             </section>
+            <section id="jpa_2.2_metamodelArrays">
+                <title>
+                    MetaModel attributes for Arrays  
+                </title>
+                <!-- See OPENJPA-2025 for details. -->
+                <para>
+                    In previous releases OpenJPA's MetaModel implementation 
generated a ListAttribute for every array. This behavior is correct if the 
array 
+                    is annotated as a PersistentCollection, but not correct 
for un-annotated arrays (e.g. byte[], char[]). In OpenJPA 2.2.0 this behavior 
was corrected 
+                    so that arrays which are not stored as 
PersistentCollections will use a SingularAttribute instead of a ListAttribute. 
+                </para>
+                <para>
+                    If youre application uses the MetaModel API and your 
entities contain arrays of any of the following types: byte[], Byte[], char[], 
Character[] and
+                    do not use the @PersistentCollection annotation with those 
fields you will need to update your application to use OpenJPA 2.2.0.
+                </para>
+                <para> In order for the existing applications to work with 
OpenJPA you may: 
+                    <itemizedlist>
+                        <listitem>
+                            <para> Regenerate the canonical metamodel 
classes</para>
+                        </listitem>
+                        <listitem>
+                            <para> Set the Compatibility property 
<literal>UseListAttributeForArrays</literal> to <literal>true</literal>in 
persistence.xml 
+                                <programlisting> &lt;property 
name="openjpa.Compatibility" 
value="UseListAttributeForArrays=true"/&gt;</programlisting>
+                            </para>
+                        </listitem>
+                    </itemizedlist>    
+                </para>
+            </section>
         </section>
     </section>
 </appendix>


Reply via email to