Home » Eclipse Projects » EclipseLink » Lazy load on OneToMany mapping does not work
Lazy load on OneToMany mapping does not work [message #644899] |
Tue, 14 December 2010 16:37 |
Matti Hansson Messages: 68 Registered: July 2009 |
Member |
|
|
Hi!
I'm using EclipseLink 1.1.4 to map a relationship where an "AreaSurface" can belong to several "Area". By querying Area by id I get the Area and its AreaSurface, but if I use a geometry query I get the AreaSurface but not its Areas. The log shows that a database query is prepared
[EL Fine]: ClientSession(15830327)--Connection(29407392)--SELECT FKFOGGUID, FNR_FR, AREANR FROM AREA WHERE (FKFOGGUID = ?)
bind => [859269b6-5200-49ab-b47f-785c4c305d4d]
but never executed. I do get the Areas if I set the OneToMany mapping in AreaSurface to eager. Any idea what may be wrong?
Here are the classes:
@Entity
public class AreaSurface {
@Id
@Column(name = "GUID")
private String uuid;
@StructConverter(name = "GeometryConverter",
converter = ConverterType.GEOMETRY_CONVERTER)
@Convert("GeometryConverter")
@Column(name = "SHAPE", columnDefinition = "MDSYS.SDO_GEOMETRY", nullable = false)
private Geometry geometry;
@OneToMany(mappedBy = "areaSurface") //if fetch = FetchType.EAGER is set it works
private List<Area> areas;
// Getters and setters..
}
@Entity
public class Area{
@Id
@Column(name = "FKFOGGUID")
private String fkfogguid;
@Column(name = "FNR_FR", insertable = false, updatable = false)
private String areaId;
@Column(name = "AREANR")
private int areaNumber;
@ManyToOne()
@JoinColumn(name = "FKFOGGUID", referencedColumnName = "GUID", insertable = false, updatable = false)
private AreaSurface areaSurface;
// ...
}
|
|
|
Re: Lazy load on OneToMany mapping does not work [message #645104 is a reply to message #644899] |
Wed, 15 December 2010 15:29 |
|
The log is showing the query being executed, not prepared.
Please include the code and query you are executing.
If something is lazy, it will not be instantiated until accessed. If you serialize the object before access, then it will be null or trigger an error.
If the object was already in the cache, then you will get the cached object back.
James : Wiki : Book : Blog : Twitter
|
|
|
Re: Lazy load on OneToMany mapping does not work [message #645155 is a reply to message #645104] |
Wed, 15 December 2010 17:44 |
Matti Hansson Messages: 68 Registered: July 2009 |
Member |
|
|
Quote: | The log is showing the query being executed, not prepared.
|
Does it really? I attached some more logs, and as you can see the eager log has the line "Execute query ReadObjectQuery(name="areaSurface" referenceClass=AreaSurface )" while the lazy log skips straight to "release unit of work".
Eager log:
[EL Finest]: UnitOfWork(3966697)--Execute query ReadAllQuery(referenceClass=AreaSurface )
[EL Finest]: ClientSession(32314330)--Execute query ReadAllQuery(referenceClass=AreaSurface)
[EL Fine]: ClientSession(32314330)--Connection(5511938)--SELECT GUID, SHAPE FROM AREA_SURFACE WHERE ((MDSYS.SDO_FILTER(SHAPE, ?, ?) = ?) AND (MDSYS.SDO_RELATE(SHAPE, ?, ?) = ?))
bind => [JGeometry (gtype=1, dim=2, srid=3006, QUERYTYPE=WINDOW, TRUE, JGeometry (gtype=1, dim=2, srid=3006, MASK=ANYINTERACT QUERYTYPE=WINDOW, TRUE]
[EL Finest]: ClientSession(32314330)--Execute query ReadAllQuery(name="areas" referenceClass=Area sql="SELECT FKFOGGUID, FNR_FR, AREANR FROM AREA WHERE (FKFOGGUID = ?)")
[EL Fine]: ClientSession(32314330)--Connection(5511938)--SELECT FKFOGGUID, FNR_FR, AREANR FROM AREA WHERE (FKFOGGUID = ?))
bind => [859269b6-5200-49ab-b47f-785c4c305d4d]
[EL Finest]: ClientSession(32314330)--Execute query ReadObjectQuery(name="areaSurface" referenceClass=AreaSurface )
[EL Finer]: UnitOfWork(3966697)--release unit of work
[EL Finer]: ClientSession(32314330)--Connection(5511938)--rollback transaction
[EL Finer]: ClientSession(32314330)--client released
Lazy log:
[EL Finest]: UnitOfWork(26193147)--Execute query ReadAllQuery(referenceClass=AreaSurface )
[EL Finest]: ClientSession(32579087)--Execute query ReadAllQuery(referenceClass=AreaSurface )
[EL Fine]: ClientSession(32579087)--Connection(27595538)--SELECT GUID, SHAPE FROM AREA_SURFACE WHERE ((MDSYS.SDO_FILTER(SHAPE, ?, ?) = ?) AND (MDSYS.SDO_RELATE(SHAPE, ?, ?) = ?))
bind => [JGeometry (gtype=1, dim=2, srid=3006, QUERYTYPE=WINDOW, TRUE, JGeometry (gtype=1, dim=2, srid=3006, MASK=ANYINTERACT QUERYTYPE=WINDOW, TRUE]
[EL Finest]: ServerSession(22238933)--Execute query ReadAllQuery(name="areas" referenceClass=Area )
[EL Finest]: ServerSession(22238933)--reconnecting to external connection pool
[EL Fine]: ServerSession(22238933)--Connection(1399004)--SELECT FKFOGGUID, FNR_FR, AREANR FROM AREA WHERE (FKFOGGUID = ?))
bind => [859269b6-5200-49ab-b47f-785c4c305d4d]
[EL Finer]: UnitOfWork(26193147)--release unit of work
[EL Finer]: ClientSession(32579087)--Connection(27595538)--rollback transaction
[EL Finer]: ClientSession(32579087)--client released
[EL Finer]: ServerSession(22238933)--client acquired
[EL Finer]: ClientSession(5174832)--Connection(322649)--begin transaction
java.lang.AssertionError: expected:<1> but was:<0>
at org.junit.Assert.fail(Assert.java:74)
at org.junit.Assert.failNotEquals(Assert.java:448)
...
Here is the unit test:
@Test
public void findAreaByPointInAreaSurface() {
Point point = new GeometryFactory(new PrecisionModel(),3006).createPoint(new Coordinate(6598735, 714690));
List<AreaSurface> surfaces = repository.findSurfacesByGeometry(point, AreaSurface.class);
assertEquals(1, surfaces.size());
AreaSurface surface = surfaces.get(0);
assertNotNull(surface.getAreas());
assertEquals(1, surface.getAreas().size()); // <-- fails if lazy!
Area area = surface.getAreas().get(0);
...
And this is the query code:
public List<AreaSurface> findSurfacesByGeometry(Geometry geometry, Class clazz) {
ReadAllQuery query = new ReadAllQuery(clazz);
query.setIsReadOnly(true);
ExpressionBuilder builder = query.getExpressionBuilder();
SpatialParameters spatialParameters = new SpatialParameters();
spatialParameters.setQueryType(SpatialParameters.QueryType.WINDOW);
SpatialParameters spatialParameters2 = new SpatialParameters();
spatialParameters2.setQueryType(SpatialParameters.QueryType.WINDOW);
SpatialParameters.Mask [] mask;
if(geometry instanceof Polygon || geometry instanceof MultiPolygon) {
mask = new SpatialParameters.Mask [] {
SpatialParameters.Mask.EQUAL,
SpatialParameters.Mask.OVERLAPBDYDISJOINT,
SpatialParameters.Mask.OVERLAPBDYINTERSECT,
SpatialParameters.Mask.CONTAINS,
SpatialParameters.Mask.COVERS,
SpatialParameters.Mask.INSIDE,
SpatialParameters.Mask.COVEREDBY,
SpatialParameters.Mask.ON
}; // Basically ANYINTERACT - TOUCH.
} else {
mask = new SpatialParameters.Mask [] {
SpatialParameters.Mask.ANYINTERACT
};
}
spatialParameters2.setMasks(mask);
JGeometry jgeometry = GeometryConverter.toJGeometry(geometry);
Expression filter = SpatialExpressionFactory.filter(builder.get("geometry"), jgeometry, spatialParameters);
Expression relate = SpatialExpressionFactory.relate(builder.get("geometry"), jgeometry, spatialParameters2);
Expression spatialCriteria = filter.and(relate);
query.setSelectionCriteria(spatialCriteria);
return (List<AreaSurface>) entityManager.getActiveSession().executeQuery(query);
}
Thanks alot!
|
|
| | | | | |
Goto Forum:
Current Time: Fri Apr 19 20:50:01 GMT 2024
Powered by FUDForum. Page generated in 0.03324 seconds
|