Announcement Announcement Module
Collapse
No announcement yet.
Many to One mapping breaking seemingly unrelated relationship Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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

    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

  • #2
    I was able to successfully create your project using the script provided. I did this with Roo trunk, as per the attached screen shot.

    If the error happened when using the web UI, would you mind elaborating on what steps you need to follow within the web UI to cause the error?

    Comment

    Working...
    X