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

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