I'm running EclipseLink 2.6.4 with static weaving on Java 8 SE, and I have the following entities:
@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;
}
}
When I execute the following transaction:
public void removeById(long id) {
em.getTransaction().begin();
MyObject myObjectRef = em.getReference(MyObject.class, id);
em.remove(myObjectRef);
em.getTransaction().commit();
em.clear();
}
I can see the following queries:
SELECT ID, SOURCE_ID FROM MYOBJECT WHERE (ID = ?)
SELECT ID, NAME FROM MYSOURCE WHERE (ID = ?)
DELETE FROM MYOBJECT WHERE (ID = ?)
And more surprisingly, if I change the fetch type from LAZY to EAGER in the MyObject -> MySource association, then I obtain:
DELETE FROM MYOBJECT WHERE (ID = ?)
What's wrong with LAZY loading when a proxy is used to remove an entity?