You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by Donald Woods <dw...@apache.org> on 2010/11/08 20:58:14 UTC

Re: svn commit: r1032116 - New test failures on MSSQL and DB2

Fay, it looks like this new Person entity duplicates an existing one in
the lockmgr tests -

org.apache.openjpa.persistence.lockmgr.TestLocking.testExtendedLockScope
    <openjpa-2.1.0-SNAPSHOT-runknown fatal store error>
org.apache.openjpa.persistence.RollbackException: The transaction has
been rolled back. See the nested exceptions for details on the errors
that occurred.
    FailedObject: org.apache.openjpa.persistence.lockmgr.Person@42df79
    at
org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:584)
    <openjpa-2.1.0-SNAPSHOT-runknown fatal store error>
org.apache.openjpa.persistence.RollbackException: The transaction has
been rolled back. See the nested exceptions for details on the errors
that occurred.
    FailedObject: org.apache.openjpa.persistence.lockmgr.Person@42df79

Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: Cannot
insert the value NULL into column 'name', table 'OPENJPA.dbo.Person';
column does not allow nulls. INSERT fails. {prepstmnt 19498735 INSERT
INTO Person (id, firstName, lastName) VALUES (?, ?, ?) [params=?, ?, ?]}


-Donald


On 11/6/10 1:24 PM, faywang@apache.org wrote:
> Author: faywang
> Date: Sat Nov  6 17:24:17 2010
> New Revision: 1032116
> 
> URL: http://svn.apache.org/viewvc?rev=1032116&view=rev
> Log:
> OPENJPA-1762: lock join table when extended pessimistic scope is used
> 
> Added:
>     openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/Person.java   (with props)
>     openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/PhoneNumber.java   (with props)
>     openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestLocking.java   (with props)
> Modified:
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ContainerFieldStrategy.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MapTableFieldStrategy.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java
> 
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java?rev=1032116&r1=1032115&r2=1032116&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java Sat Nov  6 17:24:17 2010
> @@ -26,6 +26,10 @@ import java.util.ArrayList;
>  import java.util.List;
>  
>  import org.apache.openjpa.jdbc.meta.ClassMapping;
> +import org.apache.openjpa.jdbc.meta.FieldMapping;
> +import org.apache.openjpa.jdbc.meta.Strategy;
> +import org.apache.openjpa.jdbc.meta.strats.ContainerFieldStrategy;
> +import org.apache.openjpa.jdbc.schema.ForeignKey;
>  import org.apache.openjpa.jdbc.sql.DBDictionary;
>  import org.apache.openjpa.jdbc.sql.SQLBuffer;
>  import org.apache.openjpa.jdbc.sql.SQLFactory;
> @@ -124,6 +128,7 @@ public class PessimisticLockManager
>          ClassMapping mapping = (ClassMapping) sm.getMetaData();
>  
>          List<SQLBuffer> sqls = getLockRows(dict, id, mapping, fetch, _store.getSQLFactory()); 
> +        lockJoinTables(sqls, dict, id, mapping, fetch, _store.getSQLFactory());
>  
>          ensureStoreManagerTransaction();
>          Connection conn = _store.getConnection();
> @@ -163,6 +168,21 @@ public class PessimisticLockManager
>          sqls.add(select.toSelect(true, fetch));
>          return sqls;
>      }
> +    
> +    protected void lockJoinTables(List<SQLBuffer> sqls, DBDictionary dict, Object id, ClassMapping mapping,
> +            JDBCFetchConfiguration fetch, SQLFactory factory) {
> +        FieldMapping[] fms = mapping.getFieldMappings();
> +        for (int i = 0; i < fms.length; i++) {
> +            Strategy strat = fms[i].getStrategy();
> +            if (strat instanceof ContainerFieldStrategy) {
> +                ForeignKey fk = ((ContainerFieldStrategy)strat).getJoinForeignKey();
> +                Select select = factory.newSelect();
> +                select.select(fk.getColumns());
> +                select.whereForeignKey(fk, id, fms[i].getDefiningMapping(), _store);
> +                sqls.add(select.toSelect(true, fetch));
> +            }
> +        }
> +    }
>  
>      /**
>       * Enforce that we have an actual transaction in progress so that we can
> 
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ContainerFieldStrategy.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ContainerFieldStrategy.java?rev=1032116&r1=1032115&r2=1032116&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ContainerFieldStrategy.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ContainerFieldStrategy.java Sat Nov  6 17:24:17 2010
> @@ -77,7 +77,7 @@ public abstract class ContainerFieldStra
>          appendSize(sql, sel, joins);
>      }
>  
> -    protected abstract ForeignKey getJoinForeignKey();
> +    public abstract ForeignKey getJoinForeignKey();
>  
>      public void appendSize(SQLBuffer sql, Select sel, Joins joins) {
>          DBDictionary dict = field.getMappingRepository().getDBDictionary();
> 
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MapTableFieldStrategy.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MapTableFieldStrategy.java?rev=1032116&r1=1032115&r2=1032116&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MapTableFieldStrategy.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MapTableFieldStrategy.java Sat Nov  6 17:24:17 2010
> @@ -182,7 +182,7 @@ public abstract class MapTableFieldStrat
>          return field.join(joins, forceOuter, true);
>      }
>  
> -    protected ForeignKey getJoinForeignKey() {
> +    public ForeignKey getJoinForeignKey() {
>          return field.getJoinForeignKey();
>      }
>  
> 
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java?rev=1032116&r1=1032115&r2=1032116&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java Sat Nov  6 17:24:17 2010
> @@ -597,7 +597,7 @@ public abstract class StoreCollectionFie
>          return loadElement(null, store, fetch, res, joins);
>      }
>  
> -    protected ForeignKey getJoinForeignKey() {
> +    public ForeignKey getJoinForeignKey() {
>          return getJoinForeignKey(getDefaultElementMapping(false));
>      }
>      
> 
> Added: openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/Person.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/Person.java?rev=1032116&view=auto
> ==============================================================================
> --- openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/Person.java (added)
> +++ openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/Person.java Sat Nov  6 17:24:17 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.lockmgr;
> +
> +import java.io.Externalizable;
> +import java.io.IOException;
> +import java.io.ObjectInput;
> +import java.io.ObjectOutput;
> +import java.util.List;
> +
> +import javax.persistence.Entity;
> +import javax.persistence.Id;
> +import javax.persistence.JoinColumn;
> +import javax.persistence.ManyToMany;
> +import javax.persistence.ManyToOne;
> +
> +
> +@Entity
> +public class Person implements Externalizable {
> +
> +    private int id;
> +
> +    private String firstName;
> +    private String lastName;
> +    private List<PhoneNumber> phoneNumbers;
> +    
> +    @Id
> +    public int getId() {
> +        return id;
> +    }
> +
> +    public void setId(int id) {
> +        this.id = id;
> +    }
> +
> +    public String getFirstName() {
> +        return firstName;
> +    }
> +
> +    public void setFirstName(String firstName) {
> +        this.firstName = firstName;
> +    }
> +
> +    public String getLastName() {
> +        return lastName;
> +    }
> +
> +    public void setLastName(String lastName) {
> +        this.lastName = lastName;
> +    }
> +    
> +    @ManyToMany(mappedBy = "owners")
> +    public List<PhoneNumber> getPhoneNumbers(){
> +        return phoneNumbers;
> +    }
> +    
> +    public void setPhoneNumbers(List<PhoneNumber> numbers){
> +        phoneNumbers = numbers;
> +    }
> +
> +    public String toString() {
> +        return this.getClass().getName() + '@'
> +            + Integer.toHexString(System.identityHashCode(this)) + "[id="
> +            + getId() + "] first=" + getFirstName()
> +            + ", last=" + getLastName() + " phone numbers="+phoneNumbers.toString();
> +    }
> +
> +    public void readExternal(ObjectInput in) throws IOException,
> +        ClassNotFoundException {
> +        id = in.readInt();
> +        firstName = (String) in.readObject();
> +        lastName = (String) in.readObject();
> +        phoneNumbers = (List<PhoneNumber>) in.readObject();
> +    }
> +
> +    public void writeExternal(ObjectOutput out) throws IOException {
> +        out.writeInt(id);
> +        out.writeObject(firstName);
> +        out.writeObject(lastName);
> +        out.writeObject(phoneNumbers);
> +    }
> +}
> 
> Propchange: openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/Person.java
> ------------------------------------------------------------------------------
>     svn:eol-sytle = native
> 
> Added: openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/PhoneNumber.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/PhoneNumber.java?rev=1032116&view=auto
> ==============================================================================
> --- openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/PhoneNumber.java (added)
> +++ openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/PhoneNumber.java Sat Nov  6 17:24:17 2010
> @@ -0,0 +1,53 @@
> +/*
> + * 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.lockmgr;
> +
> +import java.io.Serializable;
> +import java.util.List;
> +
> +import javax.persistence.Entity;
> +import javax.persistence.Id;
> +import javax.persistence.ManyToMany;
> +
> +@Entity
> +public class PhoneNumber implements Serializable {
> +    private static final long serialVersionUID = 6918497432632022604L;
> +
> +    PhoneNumber() {
> +    }
> +
> +    public PhoneNumber(String p) {
> +        number = p;
> +    }
> +
> +    @Id
> +    String number;
> +
> +    @ManyToMany
> +    List<Person> owners;
> +
> +    public void setOwners(List<Person> o) {
> +        owners = o;
> +    }
> +
> +    @Override
> +    public String toString() {
> +        return number;
> +    }
> +}
> 
> Propchange: openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/PhoneNumber.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> Added: openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestLocking.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestLocking.java?rev=1032116&view=auto
> ==============================================================================
> --- openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestLocking.java (added)
> +++ openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestLocking.java Sat Nov  6 17:24:17 2010
> @@ -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.lockmgr;
> +
> +import java.util.Arrays;
> +import java.util.HashMap;
> +import java.util.List;
> +import java.util.Map;
> +
> +import javax.persistence.LockModeType;
> +import javax.persistence.PessimisticLockScope;
> +
> +import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
> +import org.apache.openjpa.persistence.test.SQLListenerTestCase;
> +
> +public class TestLocking extends SQLListenerTestCase {
> +    String _phone = "5075555555";
> +
> +    public void setUp() {
> +        super.setUp(CLEAR_TABLES, Person.class, PhoneNumber.class
> +        // ,"openjpa.Log", "SQL=trace"
> +            );
> +        populate();
> +    }
> +
> +    public void testExtendedLockScope() throws Exception {
> +        Map<String, Object> props = new HashMap<String, Object>();
> +        props.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED);
> +
> +        OpenJPAEntityManagerSPI em1 = emf.createEntityManager();
> +        OpenJPAEntityManagerSPI em2 = emf.createEntityManager();
> +        CommitterThread committer = new CommitterThread(em2);
> +
> +        em1.getTransaction().begin();
> +        Person e1 = em1.find(Person.class, 1);
> +        assertEquals(1, e1.getPhoneNumbers().size());
> +
> +        // This SHOULD lock Employee with id=1 AND the join table.
> +        // 
> +        // pg 86
> +        // Element collections and relationships owned by the entity that are contained in join tables will be
> +        // locked if the javax.persistence.lock.scope property is specified with a value of
> +        // PessimisticLockScope.EXTENDED. The state of entities referenced by such relationships will
> +        // not be locked (unless those entities are explicitly locked). This property may be passed as an argument
> +        // to the methods of the EntityManager, Query, and TypedQuery interfaces that allow lock modes
> +        // to be specified or used with the NamedQuery annotation.
> +
> +        em1.refresh(e1, LockModeType.PESSIMISTIC_FORCE_INCREMENT, props);
> +
> +        // Kick off the committer thread
> +        committer.start();
> +
> +        // Make sure to sleep at least for 5 seconds AFTER the committer calls commit
> +        while (System.currentTimeMillis() - committer.sleepStartTime < 5000) {
> +            Thread.sleep(5000);
> +        }
> +        // The committer should still be waiting because the em1.refresh(...) call should have locked the join table and
> +        // the remove can't complete
> +        assertFalse(committer.commitComplete);
> +        em1.getTransaction().commit();
> +        em1.close();
> +        // wait for child thread to finish
> +        committer.join();
> +    }
> +
> +    private class CommitterThread extends Thread {
> +        OpenJPAEntityManagerSPI _em2;
> +        boolean inCommit = false;
> +        boolean commitComplete = false;
> +        long sleepStartTime = Long.MAX_VALUE;
> +
> +        public CommitterThread(OpenJPAEntityManagerSPI e) {
> +            _em2 = e;
> +        }
> +
> +        @Override
> +        public void run() {
> +            _em2.getTransaction().begin();
> +            PhoneNumber phoneNumber = _em2.find(PhoneNumber.class, _phone);
> +            _em2.remove(phoneNumber);
> +            inCommit = true;
> +            sleepStartTime = System.currentTimeMillis();
> +            _em2.getTransaction().commit();
> +            commitComplete = true;
> +            _em2.close();
> +        }
> +    }
> +
> +    private void populate() {
> +        OpenJPAEntityManagerSPI em = emf.createEntityManager();
> +        em.getTransaction().begin();
> +
> +        PhoneNumber p = new PhoneNumber(_phone);
> +        List<PhoneNumber> numbers = Arrays.asList(new PhoneNumber[] { p });
> +
> +        Person e1 = new Person();
> +        e1.setId(1);
> +        e1.setPhoneNumbers(numbers);
> +        Person e2 = new Person();
> +        e2.setId(2);
> +        e2.setPhoneNumbers(numbers);
> +
> +        p.setOwners(Arrays.asList(new Person[] { e1, e2 }));
> +        em.persist(e1);
> +        em.persist(e2);
> +        em.persist(p);
> +
> +        em.getTransaction().commit();
> +        em.close();
> +    }
> +}
> 
> Propchange: openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestLocking.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> 
>