475 words

"Attempt to lock a non entity object" error

#1
2013-03-30 17:56

Probably a simple answer for someone who's been using ObjectDB for awhile:

I'm reading objects from the database outside a transaction (inside doesn't seem to matter).

First cycle of doEdit and then doCancelEdit works fine.

Second time I doEdit produces the error "Attempt to lock a non entity object"

session.rollback() is somehow causing the problem (found through debugging)

Is this enough information for someone to suggest what might be happening and how to fix it?

public void doEdit() {
try {
    session.beginTransaction();
    session.lock(subjectJList.getSelectedValue(),
      LockModeType.PESSIMISTIC_WRITE);
.
.
} //doEdit
//-----------------------------------------------------------
public void doCancelEdit() {
try {
    session.rollback();
.
.
.
} //doCancelEdit
-------------------------------------------------------------
Attempt to lock a non entity object

 

AlphaOne
AlphaOne's picture
Joined on 2013-03-14
User Post #4
#2
2013-03-30 19:14

Error was caused - from the ObjectDB manual - by:

"The following operations clear the entire persistence context and detach all managed entity objects:

... Rolling back a transaction - either by invocation of rollback or by a commit failure."

Quite different behavior from what I expected and would prefer. 

AlphaOne
AlphaOne's picture
Joined on 2013-03-14
User Post #5
#3
2013-03-30 21:27

It is correct. All the entity objects are detached on rollback.

This is how it should work in JPA and it is different from JDO.

A new build (2.4.7_15) enables now using JDO behavior on rollback with JPA.

To keep the entity objects managed with their current changes:

    PersistenceManager pm = em.unwrap(PersistenceManager.class);
    pm.currentTransaction().setRestoreValues(false);

To keep the entity objects managed but restore their content (discarding changes if any):

    PersistenceManager pm = em.unwrap(PersistenceManager.class);
    pm.currentTransaction().setRestoreValues(true);

The first option may be more efficient.

You need to call setRetainValues once per EntityManager.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #1,477
#4
2013-03-30 23:14

I've downloaded the new build and tried the code above that uses a JDO Transaction with beginTransaction(), lock(), and rollback() on the same JDO Transaction, and then beginTransaction(), lock(), and rollback() on a JPA EntityTransaction and I'm still getting the same error. Am I missing something that would be obvious to someone else?

AlphaOne
AlphaOne's picture
Joined on 2013-03-14
User Post #6
#5
2013-03-31 09:05

Please follow the posting instructions and provide a minimal test case that demonstrates the problem.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #1,479
#6
2013-03-31 23:53
[ObjectDB 2.4.7_15 Enhancer]
1 persistable type has been enhanced:
    Person
 
[ObjectDB 2.4.7_15 Enhancer]
1 persistable type has been enhanced:
    Test
 
Stored: Ron
After find and first lock: Ron
Exception in thread "main" [ObjectDB 2.4.7_15] java.lang.IllegalArgumentException
Attempt to lock a non entity object (error 635)
at com.objectdb.jpa.EMImpl.lock(EMImpl.java:783)
at com.objectdb.jpa.EMImpl.lock(EMImpl.java:753)
at Test.main(Test.java:34)
at Enhance.main(Enhance.java:7)
import javax.persistence.Entity;
//----------------
@Entity
    class Person {
        String name;
        //----------------
        public Person(String name) {
            this.name = name;
        } //Person
        //----------------
        public void setName(String name) {
            this.name = name;
        } //setName
    //----------------
} //Person
 
import javax.jdo.PersistenceManager;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.LockModeType;
import javax.persistence.Persistence;
 
//----------------
@Entity
public class Test {
//----------------
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory(
          "objectdb:D:\\eclipse\\workspace\\TestProject\\Storage.odb");
        EntityManager em = emf.createEntityManager();
        Person p = new Person("Ron");
        em.getTransaction().begin();
        em.persist(p);
        em.getTransaction().commit();
        System.out.println("Stored: " + p.name);
        emf.close();
        //-------
        emf = Persistence.createEntityManagerFactory(
          "objectdb:D:\\eclipse\\workspace\\TestProject\\Storage.odb");
        em = emf.createEntityManager();
        PersistenceManager pm = em.unwrap(PersistenceManager.class);
        pm.currentTransaction().setRetainValues(true);
        em.getTransaction().begin();
        p = em.find(Person.class, 1);
        em.lock(p, LockModeType.PESSIMISTIC_WRITE);
        System.out.println("After find and first lock: " + p.name);
        em.getTransaction().rollback();
        em.getTransaction().begin();
        // next line throws IllegalArgumentException
        em.lock(p, LockModeType.PESSIMISTIC_WRITE);
        System.out.println("After second lock before update: " + p.name);
        p.setName("Jim");
        System.out.println("After update before second rollback: " + p.name);
        em.getTransaction().rollback();
        System.out.println("After second rollback: " + p.name);
        emf.close();
    } //main
//----------------
} //Test
AlphaOne
AlphaOne's picture
Joined on 2013-03-14
User Post #7
#7
2013-04-02 03:30

You are right. Unfortunately in #3 above setRestoreValues was replaced with setRetainValues (it is fixed now).

Sorry for the error.  After switching to setRestoreValues your test works.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #1,482
#8
2013-04-02 12:16

(You overlooked the needed change to the last line of #3 above:

"You need to call setRetainValues once per EntityManager.")

Yup, my application also works with the fix.

The new behavior and your quick fix are greatly appreciated.

AlphaOne
AlphaOne's picture
Joined on 2013-03-14
User Post #8

Post Reply

Please read carefully the posting instructions - before posting to the ObjectDB website.

  • You may have to disable pop up blocking in order to use the toolbar (e.g. in Chrome).
  • Use ctrl + right click to open the browser context menu in the editing area (e.g. for using a browser spell checker).
  • To insert formatted lines (e.g. Java code, stack trace) - select a style in the toolbar and then insert the text in the new created block.
  • Avoid overflow of published source code examples by breaking long lines.
  • You may mark in paragraph code words (e.g. class names) with the code style (can be applied by ctrl + D).
  • Long stack traces (> 50 lines) and complex source examples (> 100 lines) should be posted as attachments.
Attachments:
Maximum file size: 32 MB
Cancel