Issue Details (XML | Word | Printable)

Key: NUCRDBMS-525
Type: Bug Bug
Status: Closed Closed
Resolution: Won't Fix
Priority: Minor Minor
Assignee: Unassigned
Reporter: Christian Ernst
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
DataNucleus Store RDBMS

javax.jdo.Transaction.commit() hangs on an empty database when datanucleus.autoCreateSchema is set to true

Created: 13/May/11 01:47 PM   Updated: 03/Oct/11 07:38 AM   Resolved: 14/Sep/11 08:04 PM
Component/s: ORM
Affects Version/s: 3.0.0.m4
Fix Version/s: None

File Attachments: 1. Zip Archive AutoSchemaCreateHangingInCommit.zip (12 kB)

Environment: Windows XP 64 bit, JDK 1.6.0_17, MySQL 5.5.11, MySQL Connector 5.1.7

Datastore: MySQL


 Description  « Hide
On a fresh MySQL 5.5.11 database without any schema defined a certain Model can cause that the first javax.jdo.Transaction.commit() hangs when datanucleus.autoCreateSchema is set to true.
Be aware that this happens only on an empty database. In case this test hangs and gets killed and restarted it works as part of the schema
is already defined.

----------------
public class A {
private int a;
private List<A> list = new ArrayList<A>();
}
public class B extends A{
private int b;
}
------------------
<jdo>
  <package name="model">
   <class name="A">
            <field name="list" embedded="true">
         <collection element-type="A"/>
         </field>
        </class>
        <class name="B" persistence-capable-superclass="model.A"/>
  </package>
</jdo>
-----------------------
13.05.2011 13:41:52 org.datanucleus.store.rdbms.table.AbstractTable create
INFO: Creating table `DELETEME1305286912429`
13.05.2011 13:41:52 org.datanucleus.store.rdbms.table.ProbeTable findSchemaDetails
INFO: Schema Name could not be determined for this datastore
13.05.2011 13:41:52 org.datanucleus.store.rdbms.table.AbstractTable drop
INFO: Dropping table `DELETEME1305286912429`
13.05.2011 13:41:52 org.datanucleus.store.rdbms.RDBMSStoreManager initialiseSchema
INFO: Initialising Catalog "dbbench", Schema "" using "None" auto-start option
13.05.2011 13:41:52 org.datanucleus.store.rdbms.RDBMSStoreManager initialiseSchema
INFO: Catalog "dbbench", Schema "" initialised - managing 0 classes
13.05.2011 13:41:52 org.datanucleus.NucleusContext logConfiguration
INFO: ================= Persistence Configuration ===============
13.05.2011 13:41:52 org.datanucleus.NucleusContext logConfiguration
INFO: DataNucleus Persistence Factory - Vendor: "DataNucleus" Version: "3.0.0.m4"
13.05.2011 13:41:52 org.datanucleus.NucleusContext logConfiguration
INFO: DataNucleus Persistence Factory initialised for datastore URL="jdbc:mysql://localhost/dbbench" driver="com.mysql.jdbc.Driver" userName="dbbench"
13.05.2011 13:41:52 org.datanucleus.NucleusContext logConfiguration
INFO: ===========================================================
13.05.2011 13:41:52 org.datanucleus.api.jdo.metadata.JDOMetaDataManager <init>
INFO: Registering listener for metadata initialisation
13.05.2011 13:41:52 org.datanucleus.api.jdo.metadata.JDOMetaDataManager$MetaDataRegisterClassListener registerClass
INFO: Listener found initialisation for persistable class model.A
13.05.2011 13:41:52 org.datanucleus.store.StoreDataManager registerStoreData
INFO: Managing Persistence of Class : model.A [Table : `A`, InheritanceStrategy : new-table]
13.05.2011 13:41:52 org.datanucleus.store.rdbms.table.AbstractTable create
INFO: Creating table `A`
13.05.2011 13:41:52 org.datanucleus.store.rdbms.table.TableImpl createForeignKeys
INFO: Creating foreign key constraint : "A_FK1" in catalog "" schema ""
13.05.2011 13:41:52 org.datanucleus.store.rdbms.table.AbstractTable create
INFO: Creating table `SEQUENCE_TABLE`
13.05.2011 13:41:52 org.datanucleus.store.StoreDataManager registerStoreData
INFO: Managing Persistence of Class : model.B [Table : `A`, InheritanceStrategy : superclass-table]
13.05.2011 13:41:52 org.datanucleus.store.rdbms.table.TableImpl validateColumns
INFO: Creating column `B` for table `A`
---------------------





Christian Ernst made changes - 13/May/11 01:47 PM
Field Original Value New Value
Attachment AutoSchemaCreateHangingInCommit.zip [ 11443 ]
Christian Ernst added a comment - 13/May/11 01:53 PM
Also fails with latest MySQL Connector 5.1.16

Andy Jefferson added a comment - 13/May/11 02:22 PM
There are many RDBMS that "hang" on such cases since the connection has already been used for INSERT on the table in question, and hence why we always have recommended using SchemaTool before usage.

I don't see what DataNucleus can reasonably do here other than what it is doing ... encounters A, so creates TABLE_A, encounters B, so tries to update TABLE_A for what B requires.

Andy Jefferson made changes - 13/May/11 02:22 PM
Priority Major [ 3 ] Minor [ 4 ]
Christian Ernst added a comment - 13/May/11 02:29 PM
But in my case it hangs when i create the first instance of A.
Is there not the order of the sql statements wrong ?
First do any table updates and than any instance inserts ?
----------------
Properties properties = new Properties();
try {
properties.load(new FileInputStream("datanucleus.properties"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

properties.setProperty("datanucleus.autoCreateSchema", "true");

PersistenceManagerFactory pmf = JDOHelper
.getPersistenceManagerFactory(properties);
PersistenceManager pm = pmf.getPersistenceManager();

Transaction txn = pm.currentTransaction();
txn.begin();

pm.makePersistent(new A());

// this hangs on an empty database without any tables
txn.commit();
------------

Andy Jefferson added a comment - 13/May/11 02:33 PM
Read the log ... at DEBUG level.

13:19:43,575 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Datastore.Native] - INSERT INTO `A` (`A_ID`,`A`,`LIST_A_ID_OID`,`LIST_INTEGER_IDX`) VALUES (<1>,<0>,<null>,<-1>)
13:19:43,597 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Datastore.Persist] - Execution Time = 22 ms (number of rows = 1)

...
13:19:43,639 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Datastore] - Table `A` will manage the persistence of the fields for class org.datanucleus.test.B (inheritance strategy="superclass-table")
13:19:43,639 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Datastore.Schema] - Column "`A`.`B`" added to internal representation of table.
...
13:19:43,701 (org.datanucleus.test.Main.main()) INFO [DataNucleus.Datastore.Schema] - Creating column `B` for table `A`
13:19:43,701 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Datastore.Schema] - ALTER TABLE `A` ADD COLUMN `B` INTEGER NULL

Andy Jefferson added a comment - 13/May/11 02:52 PM
Witn regards to changing how DataNucleus does things, well as you well know JDO does not define a mechanism for saying "this list of classes are all that i am persisting". Consequently DataNucleus cannot know about all possible subclasses of class A. In fact there may have been another subclass in some other package.jdo file (or with annotations) that was only encountered later in that transaction. This means that the only reliable way of handling the situation is for the user to use persistence.xml and define all classes in it, and then set a persistence property to load all classes into the StoreManager at startup (look in the docs). This would then generate all schema before any such transaction.

As a result, issues like this will always remain low priority since Mr User has ample workarounds, and I haven't got infinite time ;-)

Christian Ernst added a comment - 13/May/11 03:45 PM
Works fine when the persistent Classes have JDO Annotations.
But seems not to work when using JDO metadata files like package.jdo only.
-----------
properties.setProperty("datanucleus.PersistenceUnitName","test");
properties.setProperty("datanucleus.PersistenceUnitLoadClasses", "true");
-----------
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
        http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<persistence-unit name="test">
     <class>model.A</class>
     <class>model.B</class>
</persistence-unit>
</persistence>
-------------

Andy Jefferson added a comment - 13/May/11 04:01 PM
and indeed in that case you specify "mapping-file" not "class" in persistence.xml, and the log reveals what is found

Andy Jefferson added a comment - 14/Sep/11 08:04 PM
The provided testcase hangs after sending an INSERT and then needing to do a schema update, due to the user not notifying the persistence process of classes that are present.

The simple workaround of putting annotated classes and mapping files into persistence.xml, and using persistence property "datanucleus.PersistenceUnitLoadClasses" as true works fine on all cases present here (including this)

Andy Jefferson made changes - 14/Sep/11 08:04 PM
Status Open [ 1 ] Resolved [ 5 ]
Resolution Won't Fix [ 2 ]
Andy Jefferson made changes - 03/Oct/11 07:38 AM
Status Resolved [ 5 ] Closed [ 6 ]