我将2个对象添加到数据库,Person
和Student
(Person的子类)。当我在Person
上查询时,它会返回每个实例e两次。当我在Student
上查询时,它会返回两个实例,即使Person
不是Student
的子类。该代码基于datanucleus的jdo-test-template。我正在使用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();
for (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();
for (Student s2: c) {
System.out.println("Student: " + s2.getName() + " " + s2.getId() + " " + System.identityHashCode(s2));
}
tx.commit();
Person类与示例模板保持不变:
@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;
}
}
Student
类:
@PersistenceCapable(detachable="true")
public class Student extends Person {
public Student(long id, String name) {
super(id, name);
}
}
我还在Student
文件中添加了persistence.xml
:
<?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 all of your 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>
运行程序时,我得到以下输出:
Person: Sarah 1 454305524
Person: Sarah 1 1536471117
Person: Pete 0 1961945640
Person: Pete 0 1898155970
Student: Pete 0 1898155970
Student: Sarah 1 1536471117
查看System.identityHashCode(...)
,它为第一个查询返回4个不同的Java实例。
我做错了吗?或者是预期的输出?
修改 我刚刚确认DataNucleus 4.1.8的行为与5.0.0m1相同
修改
来自日志文件:
17:36:21,660 (main) DEBUG [DataNucleus.Query] - JDOQL Query : Compiling "SELECT FROM 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: this type=mydomain.model.Person]
17:36:21,669 (main) DEBUG [DataNucleus.Query] - JDOQL Query : Compiling "SELECT FROM mydomain.model.Person" for datastore
17:36:21,697 (main) DEBUG [DataNucleus.Query] - JDOQL Query : Compile Time for datastore = 28 ms
17:36:21,698 (main) DEBUG [DataNucleus.Query] - SELECT FROM mydomain.model.Person Query compiled to datastore query "SELECT 'mydomain.model.Person ' AS NUCLEUS_TYPE,A0.ID,A0."NAME" FROM PERSON A0 UNION SELECT 'mydomain.model.Student' AS NUCLEUS_TYPE,A0.ID,A0."NAME" FROM 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 the pool : "org.datanucleus.store.rdbms.ConnectionFactoryImpl$ManagedConnectionImpl@3c41ed1d [conn=org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@22ff4249, commitOnRelease=false, closeOnRelease=false, closeOnTxnEnd=true]" for 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 FROM mydomain.model.Person" ...
17:36:21,698 (main) DEBUG [DataNucleus.Datastore.Native] - BATCH [INSERT INTO PERSON ("NAME",ID) VALUES (<'Pete'>,<0>); INSERT INTO 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 ' AS NUCLEUS_TYPE,A0.ID,A0."NAME" FROM PERSON A0 UNION SELECT 'mydomain.model.Student' AS NUCLEUS_TYPE,A0.ID,A0."NAME" FROM 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 with id "mydomain.model.Person:1" not found in Level 1 cache [cache size = 2]
17:36:21,707 (main) DEBUG [DataNucleus.Cache] - Object with 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 to Level 1 cache (loadedFlags="[YN]")
17:36:21,709 (main) DEBUG [DataNucleus.Cache] - Object "mydomain.model.Person@1f97cf0d" (id="1") added to 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 a 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 from 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 from Level 1 cache (loadedFlags="[YY]") [cache size = 3]
17:36:21,712 (main) DEBUG [DataNucleus.Cache] - Object with id "mydomain.model.Student:0" not found in Level 1 cache [cache size = 3]
17:36:21,713 (main) DEBUG [DataNucleus.Cache] - Object with 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 to Level 1 cache (loadedFlags="[YN]")
17:36:21,713 (main) DEBUG [DataNucleus.Cache] - Object "mydomain.model.Student@49dc7102" (id="0") added to 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 a 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 FROM 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: this type=mydomain.model.Student]
17:36:21,713 (main) DEBUG [DataNucleus.Query] - JDOQL Query : Compiling "SELECT FROM mydomain.model.Student" for datastore
17:36:21,714 (main) DEBUG [DataNucleus.Query] - JDOQL Query : Compile Time for datastore = 1 ms
17:36:21,714 (main) DEBUG [DataNucleus.Query] - SELECT FROM mydomain.model.Student Query compiled to datastore query "SELECT 'mydomain.model.Student' AS NUCLEUS_TYPE,A0.ID,A0."NAME" FROM PERSON A0"
17:36:21,714 (main) DEBUG [DataNucleus.Connection] - ManagedConnection found in the pool : "org.datanucleus.store.rdbms.ConnectionFactoryImpl$ManagedConnectionImpl@3c41ed1d [conn=org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@22ff4249, commitOnRelease=false, closeOnRelease=false, closeOnTxnEnd=true]" for 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 FROM 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' AS NUCLEUS_TYPE,A0.ID,A0."NAME" FROM 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 from 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 from Level 1 cache (loadedFlags="[YY]") [cache size = 4]
我认为有趣的是Student
查询在PERSON
表上执行而没有其他参数。不确定它们如何映射数据库中的继承,但是如果所有类都映射到单个表中,那么我至少会期望一个列具有类型标识符:
17:36:21,715 (main) DEBUG [DataNucleus.Datastore.Native] - SELECT 'mydomain.model.Student' AS NUCLEUS_TYPE,A0.ID,A0."NAME" FROM PERSON A0
答案 0 :(得分:1)
您尚未指定继承策略以及您希望持久性机制如何区分共享表的类。
根据{{3}}使用function getComparisonByKeyFn($key) {
return function($a, $b) use ($key) {
return $a[$key] < $b[$key] ? -1 : ($a[$key] > $b[$key] ? 1 : 0);
};
}
usort($arr, getComparisonByKeyFn('weight'));
usort($arr, getComparisonByKeyFn('key'));
usort($arr, getComparisonByKeyFn('value'));
和@Inheritance
。虽然它将默认继承策略为基类的NEW_TABLE和子类的SUPERCLASS_TABLE,但它不会默认任何鉴别器,因为可能你不想拥有一个并且从不需要分离存储在该表中的内容