Queries return duplicates in JDO/Datanucleus/H2 -
i'm adding 2 object database, person
, student
(subclass of person). when query on person
, returns each instance e twice. when query on student
, return both instances, though person
not sub-class of student
. code based on jdo-test-template datanucleus. i'm using datanucleus 5.0.0m1.
tx.begin(); person p = new person(0, "pete"); student s = new student(1, "sarah"); pm.makepersistent(p); pm.makepersistent(s); query<person> qp = pm.newquery(person.class); collection<person>cp = (collection<person>) qp.execute(); (person p2: cp) { system.out.println("person: " + p2.getname() + " " + p2.getid() + " " + system.identityhashcode(p2)); } query<student> qs = pm.newquery(student.class); collection<student>c = (collection<student>) qs.execute(); (student s2: c) { system.out.println("student: " + s2.getname() + " " + s2.getid() + " " + system.identityhashcode(s2)); } tx.commit();
the person class unchanged example template:
@persistencecapable(detachable="true") public class person { @primarykey long id; string name; public person(long id, string name) { this.id = id; this.name = name; } public string getname() { return name; } public long getid() { return id; } }
the student
class:
@persistencecapable(detachable="true") public class student extends person { public student(long id, string name) { super(id, name); } }
i added student
persistence.xml
file:
<?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="mytest"> <!-- add of model classes here --> <class>mydomain.model.person</class> <class>mydomain.model.student</class> <exclude-unlisted-classes /> <properties> <!-- update these datastore details if different --> <property name="javax.jdo.persistencemanagerfactoryclass" value="org.datanucleus.api.jdo.jdopersistencemanagerfactory"/> <property name="javax.jdo.option.connectionurl" value="jdbc:h2:mem:nucleus"/> <property name="javax.jdo.option.connectiondrivername" value="org.h2.driver"/> <property name="javax.jdo.option.connectionusername" value="sa"/> <property name="javax.jdo.option.connectionpassword" value=""/> <property name="datanucleus.schema.autocreateall" value="true"/> </properties> </persistence-unit> </persistence>
when running program, following output:
person: sarah 1 454305524 person: sarah 1 1536471117 person: pete 0 1961945640 person: pete 0 1898155970 student: pete 0 1898155970 student: sarah 1 1536471117
looking @ system.identityhashcode(...)
, returning 4 distinct java instances first query. doing wrong? or output expected?
edit confirmed datanucleus 4.1.8 behaves same 5.0.0m1
edit
from logfile:
17:36:21,660 (main) debug [datanucleus.query] - jdoql query : compiling "select mydomain.model.person" 17:36:21,668 (main) debug [datanucleus.query] - jdoql query : compile time = 8 ms 17:36:21,668 (main) debug [datanucleus.query] - querycompilation: [symbols: type=mydomain.model.person] 17:36:21,669 (main) debug [datanucleus.query] - jdoql query : compiling "select mydomain.model.person" datastore 17:36:21,697 (main) debug [datanucleus.query] - jdoql query : compile time datastore = 28 ms 17:36:21,698 (main) debug [datanucleus.query] - select mydomain.model.person query compiled datastore query "select 'mydomain.model.person ' nucleus_type,a0.id,a0."name" person a0 union select 'mydomain.model.student' nucleus_type,a0.id,a0."name" person a0" 17:36:21,698 (main) debug [datanucleus.persistence] - executioncontext.internalflush() process started using ordered flush - 2 enlisted objects 17:36:21,698 (main) debug [datanucleus.persistence] - executioncontext.internalflush() process finished 17:36:21,698 (main) debug [datanucleus.connection] - managedconnection found in pool : "org.datanucleus.store.rdbms.connectionfactoryimpl$managedconnectionimpl@3c41ed1d [conn=org.datanucleus.store.rdbms.datasource.dbcp.poolingdatasource$poolguardconnectionwrapper@22ff4249, commitonrelease=false, closeonrelease=false, closeontxnend=true]" key="org.datanucleus.executioncontextimpl@40ef3420" in factory="connectionfactory:tx[org.datanucleus.store.rdbms.connectionfactoryimpl@5b12b668]" 17:36:21,698 (main) debug [datanucleus.query] - jdoql query : executing "select mydomain.model.person" ... 17:36:21,698 (main) debug [datanucleus.datastore.native] - batch [insert person ("name",id) values (<'pete'>,<0>); insert person ("name",id) values (<'sarah'>,<1>)] 17:36:21,699 (main) debug [datanucleus.datastore] - execution time = 1 ms (number of rows = [1, 1]) on preparedstatement "org.datanucleus.store.rdbms.paramloggingpreparedstatement@1573f9fc" 17:36:21,700 (main) debug [datanucleus.datastore] - closing preparedstatement "org.datanucleus.store.rdbms.datasource.dbcp.delegatingpreparedstatement@5939a379" 17:36:21,701 (main) debug [datanucleus.datastore.native] - select 'mydomain.model.person ' nucleus_type,a0.id,a0."name" person a0 union select 'mydomain.model.student' nucleus_type,a0.id,a0."name" person a0 17:36:21,702 (main) debug [datanucleus.datastore.retrieve] - execution time = 1 ms 17:36:21,705 (main) debug [datanucleus.query] - jdoql query : execution time = 7 ms 17:36:21,707 (main) debug [datanucleus.cache] - object id "mydomain.model.person:1" not found in level 1 cache [cache size = 2] 17:36:21,707 (main) debug [datanucleus.cache] - object id "mydomain.model.person:1" not found in level 2 cache 17:36:21,708 (main) debug [datanucleus.cache] - object "mydomain.model.person@1f97cf0d" (id="mydomain.model.person:1") added level 1 cache (loadedflags="[yn]") 17:36:21,709 (main) debug [datanucleus.cache] - object "mydomain.model.person@1f97cf0d" (id="1") added level 2 cache (fields="[0, 1]", version="") 17:36:21,711 (main) debug [datanucleus.lifecycle] - object "mydomain.model.person@1f97cf0d" (id="mydomain.model.person:1") has lifecycle change : "hollow"->"p_clean" 17:36:21,711 (main) debug [datanucleus.transaction] - object "mydomain.model.person@1f97cf0d" (id="1") enlisted in transactional cache 17:36:21,712 (main) debug [datanucleus.cache] - object "mydomain.model.student@477b4cdf" (id="mydomain.model.student:1") taken level 1 cache (loadedflags="[yy]") [cache size = 3] 17:36:21,712 (main) debug [datanucleus.cache] - object "mydomain.model.person@8dbdac1" (id="mydomain.model.person:0") taken level 1 cache (loadedflags="[yy]") [cache size = 3] 17:36:21,712 (main) debug [datanucleus.cache] - object id "mydomain.model.student:0" not found in level 1 cache [cache size = 3] 17:36:21,713 (main) debug [datanucleus.cache] - object id "mydomain.model.student:0" not found in level 2 cache 17:36:21,713 (main) debug [datanucleus.cache] - object "mydomain.model.student@49dc7102" (id="mydomain.model.student:0") added level 1 cache (loadedflags="[yn]") 17:36:21,713 (main) debug [datanucleus.cache] - object "mydomain.model.student@49dc7102" (id="0") added level 2 cache (fields="[0, 1]", version="") 17:36:21,713 (main) debug [datanucleus.lifecycle] - object "mydomain.model.student@49dc7102" (id="mydomain.model.student:0") has lifecycle change : "hollow"->"p_clean" 17:36:21,713 (main) debug [datanucleus.transaction] - object "mydomain.model.student@49dc7102" (id="0") enlisted in transactional cache 17:36:21,713 (main) debug [datanucleus.query] - jdoql query : compiling "select mydomain.model.student" 17:36:21,713 (main) debug [datanucleus.query] - jdoql query : compile time = 0 ms 17:36:21,713 (main) debug [datanucleus.query] - querycompilation: [symbols: type=mydomain.model.student] 17:36:21,713 (main) debug [datanucleus.query] - jdoql query : compiling "select mydomain.model.student" datastore 17:36:21,714 (main) debug [datanucleus.query] - jdoql query : compile time datastore = 1 ms 17:36:21,714 (main) debug [datanucleus.query] - select mydomain.model.student query compiled datastore query "select 'mydomain.model.student' nucleus_type,a0.id,a0."name" person a0" 17:36:21,714 (main) debug [datanucleus.connection] - managedconnection found in pool : "org.datanucleus.store.rdbms.connectionfactoryimpl$managedconnectionimpl@3c41ed1d [conn=org.datanucleus.store.rdbms.datasource.dbcp.poolingdatasource$poolguardconnectionwrapper@22ff4249, commitonrelease=false, closeonrelease=false, closeontxnend=true]" key="org.datanucleus.executioncontextimpl@40ef3420" in factory="connectionfactory:tx[org.datanucleus.store.rdbms.connectionfactoryimpl@5b12b668]" 17:36:21,714 (main) debug [datanucleus.query] - jdoql query : executing "select mydomain.model.student" ... 17:36:21,714 (main) debug [datanucleus.datastore] - closing preparedstatement "org.datanucleus.store.rdbms.datasource.dbcp.delegatingpreparedstatement@6b8ca3c8" 17:36:21,715 (main) debug [datanucleus.datastore.native] - select 'mydomain.model.student' nucleus_type,a0.id,a0."name" person a0 17:36:21,715 (main) debug [datanucleus.datastore.retrieve] - execution time = 1 ms 17:36:21,715 (main) debug [datanucleus.query] - jdoql query : execution time = 1 ms 17:36:21,715 (main) debug [datanucleus.cache] - object "mydomain.model.student@49dc7102" (id="mydomain.model.student:0") taken level 1 cache (loadedflags="[yy]") [cache size = 4] 17:36:21,715 (main) debug [datanucleus.cache] - object "mydomain.model.student@477b4cdf" (id="mydomain.model.student:1") taken level 1 cache (loadedflags="[yy]") [cache size = 4]
i think interesting student
query executed on person
table without further parameters. not sure how map inheritance in database, if classes mapped single table @ least expect 1 column type identifier:
17:36:21,715 (main) debug [datanucleus.datastore.native] - select 'mydomain.model.student' nucleus_type,a0.id,a0."name" person a0
you haven't specified inheritance strategy , how want persistence mechanism distinguish between classes sharing table. use @inheritance
, @discriminator
per these docs. while default inheritance strategy new_table base class , superclass_table sub class, not default discriminator because maybe didn't want have 1 , never have need separating stored in table
Comments
Post a Comment