我有一个带有removeById操作的服务,其目的是从存储库中删除实体。由于我不想在删除之前获取实体的内容,因此我使用getReference()而不是find()来获取实体。
名为' MyObject'的实体与名为' MySource'的实体具有@ManyToOne关联,并且获取类型设置为LAZY。 当我得到一个' MyObject'的实例的引用时我从数据库中移除了该实例,这两个实例都是“我的对象”。和' MySource'在移除实例之前先进行水合作用。
示例代码:
@Entity
public class MyObject {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@ManyToOne(fetch = FetchType.LAZY)
private final MySource source;
public MyObject(MySource source) {
this.source = source;
}
protected MyObject() {
this.source = null;
}
public long id() {
return this.id;
}
public MySource source() {
return this.source;
}
@Override
public boolean equals(Object obj) {
boolean equals = this == obj;
if (!equals && obj instanceof MyObject) {
MyObject other = (MyObject) obj;
equals = other.id() == id;
}
return equals;
}
@Override
public int hashCode() {
return (int) id % 16;
}
}
@Entity
public class MySource {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
public MySource(String name) {
this.name = name;
}
protected MySource() {
this.name = "";
}
@Column
private final String name;
public long id() {
return id;
}
public String name() {
return this.name;
}
@Override
public boolean equals(Object obj) {
boolean equals = this == obj;
if (!equals && obj instanceof MySource) {
MySource other = (MySource) obj;
equals = other.id() == id;
}
return equals;
}
@Override
public int hashCode() {
return (int) id % 16;
}
}
public void removeById(long id) {
em.getTransaction().begin();
MyObject myObjectRef = em.getReference(MyObject.class, id);
em.remove(myObjectRef);
em.getTransaction().commit();
em.clear();
}
提交事务时,我可以看到以下查询:
更令人惊讶的是,如果我在“我的对象”中将提取类型从LAZY更改为EAGER。 - > ' MYSOURCE'协会,然后我获得:
这次代理人没有水合作用。
当使用代理删除实体时,LAZY加载有什么问题?当fetch类型设置为EAGER时,为什么代理不会被水合?
我是否遗漏了某些内容,或者我在EclipseLink中遇到了一些错误?
(Java 8 SE上的EclipseLink 2.6.4 +静态编织)。
附加说明
我认为代理人太热切地补充水分。例如,像this.someAssociatedEntity = other.someAssociatedEntity这样的语句会发出一个SELECT来获取该关联实体,尽管该关联是使用LAZY提取类型注释的。
我希望只有在访问关联实体的字段时才会发生SELECT。
出于调试目的: 在“MyObject”之前删除MySource表时的堆栈跟踪实体被删除:
Error Code: 0
Call: SELECT ID, NAME FROM MYSOURCE WHERE (ID = ?)
bind => [1]
Query: ReadObjectQuery(name="source" referenceClass=MySource )
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:340)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.processExceptionForCommError(DatabaseAccessor.java:1620)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:676)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:560)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2056)
at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:306)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.selectOneRow(DatasourceCallQueryMechanism.java:714)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectOneRowFromTable(ExpressionQueryMechanism.java:2803)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectOneRow(ExpressionQueryMechanism.java:2756)
at org.eclipse.persistence.queries.ReadObjectQuery.executeObjectLevelReadQuery(ReadObjectQuery.java:555)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1175)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:904)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1134)
at org.eclipse.persistence.queries.ReadObjectQuery.execute(ReadObjectQuery.java:441)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1222)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1857)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1839)
at org.eclipse.persistence.internal.indirection.QueryBasedValueHolder.instantiate(QueryBasedValueHolder.java:133)
at org.eclipse.persistence.internal.indirection.QueryBasedValueHolder.instantiateForUnitOfWorkValueHolder(QueryBasedValueHolder.java:151)
at org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiateImpl(UnitOfWorkValueHolder.java:160)
at org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiate(UnitOfWorkValueHolder.java:234)
at org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getValue(DatabaseValueHolder.java:89)
at example.MyObject._persistence_get_source(MyObject.java)
at example.MyObject._persistence_get_source_vh(MyObject.java)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor.getAttributeValueFromObject(MethodAttributeAccessor.java:82)
at org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor.getAttributeValueFromObject(MethodAttributeAccessor.java:61)
at org.eclipse.persistence.mappings.DatabaseMapping.getAttributeValueFromObject(DatabaseMapping.java:657)
at org.eclipse.persistence.mappings.ForeignReferenceMapping.getAttributeValueFromObject(ForeignReferenceMapping.java:1003)
at org.eclipse.persistence.mappings.ObjectReferenceMapping.earlyPreDelete(ObjectReferenceMapping.java:841)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1412)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1531)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:278)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:134)
at test.Main.test(Main.java:203)
at test.Main.main(Main.java:42)