Many to One mapping breaking seemingly unrelated relationship
In my model I have a graph composed of Panels and Edges, where an edge must reference two Panels, and a Panel can have many edges linked to and from itself. Works fine. Great.
Later on I add in some seemingly unrelated classes for Selections. The only overlap is that the Selections reference the RoomResource (which holds an identifier, and is inherited by Panels and Edges).
After hours of painful experimentation I realised that this step was causing the Edge controller to only see the last N-1 Panels .... i.e. If I add three new Panels, then create and Edge where I want to choose from those three Panels for the to and from points of the edge, I only see two panels. In other controllers (e.g. the Room) I CAN see all three Panels so it's not a Hibernate/flush issue.
I can only think at the moment that this is a problem with ROO, but I'm happy to be corrected.
The full script is included below. Check out the LAST TWO LINES for the code which breaks it.
Please help :rolleyes:
Quote:
create project -topLevelPackage com.sefol.PLESpaces
install jpa -provider HIBERNATE -database HYPERSONIC_IN_MEMORY
// Create the abstract base class Resource ID
// Would be great to make the resourceId UNIQUE, but this isn't supported by JSR303 or Hibernate
new persistent class jpa -name ~.domain.RoomResource
add field number -fieldName resourceId -type java.lang.Long -notNull
// Now create our BasePanel which inherits from Resource
new persistent class jpa -name ~.domain.BasePanel -extends ~.domain.RoomResource -testAutomatically
// Now create our BaseEdge which inherits from Resource
new persistent class jpa -name ~.domain.BaseEdge -extends ~.domain.RoomResource -testAutomatically
// Fill our BasePanel with the appropriate fields
add field string -class ~.domain.BasePanel -fieldName text
add field string -class ~.domain.BasePanel -fieldName title
add field number -class ~.domain.BasePanel -type java.lang.Integer -fieldName x
add field number -class ~.domain.BasePanel -type java.lang.Integer -fieldName y
add field number -class ~.domain.BasePanel -type java.lang.Integer -fieldName width
add field number -class ~.domain.BasePanel -type java.lang.Integer -fieldName height
// Fill our BaseEdge with the appropriate fields
add field boolean -class ~.domain.BaseEdge -fieldName fromArrow
add field boolean -class ~.domain.BaseEdge -fieldName toArrow
add field string -class ~.domain.BaseEdge -fieldName colour
add field string -class ~.domain.BaseEdge -fieldName label
// Make our BaseEdge have a reference to a fromPanel and a toPanel
add field reference jpa -class ~.domain.BaseEdge -fieldName fromPanel -type ~.domain.BasePanel -notNull
add field reference jpa -class ~.domain.BaseEdge -fieldName toPanel -type ~.domain.BasePanel -notNull
// Link the BasePanel to the BaseEdge by having each panel contain a set of all the edges which lead from it, and lead to it.
// We shall use a custom method to unify these into a list of all edges if necessary.
add field set jpa -class ~.domain.BasePanel -fieldName fromEdges -element ~.domain.BaseEdge -mappedBy fromPanel -notNull false
add field set jpa -class ~.domain.BasePanel -fieldName toEdges -element ~.domain.BaseEdge -mappedBy toPanel -notNull false
// Install some finders, just for fun, to find edges connected to a Panel
install finder -class ~.domain.BaseEdge -finderName findBaseEdgesByToPanel
install finder -class ~.domain.BaseEdge -finderName findBaseEdgesByFromPanel
// Logging
configure logging -level DEBUG -package WEB
// Room
// Add in the idea of a Room which contains the BasePanels and BaseEdges
new persistent class jpa -name ~.domain.Room -testAutomatically
add field number -type java.lang.Long -fieldName roomId -class ~.domain.Room -notNull
add field string -class ~.domain.Room -fieldName text
add field string -class ~.domain.Room -fieldName title
// Linking Panels to Spaces
// First, I need to make a link from the Panel to the Spaces
add field reference jpa -class ~.domain.BasePanel -fieldName Room -type ~.domain.Room
// Now, lets make a set which hold references to all the BasePanels by their resourceId
add field set jpa -class ~.domain.Room -fieldName panels -element ~.domain.BasePanel -mappedBy Room -notNull false
// Now, lets extend the BasePanel with a concrete YouTube panel, containing a url
new persistent class jpa -name ~.domain.YouTubePanel -extends ~.domain.BasePanel -testAutomatically
// Add a special YouTube panel field - url
add field string -class ~.domain.YouTubePanel -fieldName url
// Now lets create two YouTubePanels, linked into a Room, and see if the Room shows the "panels" set correctly or if we need a finder.
// Linking Edges to Spaces
add field reference jpa -class ~.domain.BaseEdge -fieldName Room -type ~.domain.Room
add field set jpa -class ~.domain.Room -fieldName edges -element ~.domain.BaseEdge -mappedBy Room -notNull false
// Controllers for the first parts
new controller automatic -name ~.web.BasePanelController -formBackingObject ~.domain.BasePanel
new controller automatic -name ~.web.BaseEdgeController -formBackingObject ~.domain.BaseEdge
new controller automatic -name ~.web.RoomController -formBackingObject ~.domain.Room
new controller automatic -name ~.web.YouTubePanelController -formBackingObject ~.domain.YouTubePanel
// Now lets add a basic Person class
new persistent class jpa -name ~.domain.Person -testAutomatically
add field string -class ~.domain.Person -fieldName name
// Now lets link the People into the Room
add field reference jpa -class ~.domain.Person -fieldName Room -type ~.domain.Room
add field set jpa -class ~.domain.Room -fieldName people -element ~.domain.Person -mappedBy Room -notNull false
new controller automatic -name ~.web.PersonController -formBackingObject ~.domain.Person
// Next, lets worry about Selections.
new persistent class jpa -name ~.domain.PanelSelection -testAutomatically
add field number -class ~.domain.PanelSelection -fieldName panelSelectionId -type java.lang.Long -notNull
// Add a reference to the Person who has made the selection
add field reference jpa -class ~.domain.PanelSelection -fieldName selectionCreator -type ~.domain.Person
new controller automatic -name ~.web.PanelSelectionController -formBackingObject ~.domain.PanelSelection
// ***
// Now lets link the Selections into the Rooms so we know which selections are active :
add field reference jpa -class ~.domain.PanelSelection -fieldName Room -type ~.domain.Room
add field set jpa -class ~.domain.Room -fieldName selections -element ~.domain.PanelSelection -mappedBy Room -notNull false
// ***
// THE FOLLOWING TWO LINES CAUSE THE EDGE CREATION HANDLER TO ONLY SHOW N-1 OF THE AVAILABLE PANELS
add field reference jpa -class ~.domain.RoomResource -fieldName panelSelection -type ~.domain.PanelSelection
add field set jpa -class ~.domain.PanelSelection -fieldName selectedResources -element ~.domain.RoomResource -mappedBy panelSelection