java - Hibernate/JPA many-to-many relation through 2 intermediate tables -
i have following case (in different domain described, analogical , more comprehensive think) - db history of people presence in buildings:
- people generating signals based on current detected location (all captured signals stored in
locationsingaltable). - some of these signals recognized events - when detected around building's gates (gates not on model diagram simplicity). full history of such events stored in
detectioneventtable (and additionaldetectioneventhistorytable temporal distinction of similar records). - based on business logic of these events identified person's entry/exit to/from buildings , stored in
presencetable (with full historical register of presence changes based on additionalpresencehistorytable).
db schema [only minimum of table fields]:
question 1: proper orm (based on hibernate/jpa api) allow access detectionevent object directly presence object? there mapping:
entry_detectioneventhistory_idtable field =>entrydetectioneventobject referenceexit_detectioneventhistory_idtable field =>exitdetectioneventobject reference
... considering person_id detectionevent equal person_id presence.
this kind of many-to-many relationship between these tables through 2 intermediate , independent tables (detectioneventhistory , person). documentation examples focus on single intermediate table kind of relation.
i know can calculate on demand every presence object, utilizing @manytoone , @onetomany mappings sequentially, adding these methods presence class:
public detectionevent getentrydetectionevent() { return entrydetectioneventhistory.getdetectioneventfor(person.getid()); } public detectionevent getexitdetectionevent() { return exitdetectioneventhistory.getdetectioneventfor(person.getid()); } ... , additional getdetectioneventfor(...) method detectioneventhistory class:
@jsonignore public detectionevent getdetectioneventfor(long personid) { (detectionevent detectionevent : detectioneventlist) { if (detectionevent.getperson().getid() == personid) { return detectionevent; } } return null; } ... , i'll desired detectionevent object. seems highly inefficient when fetching list of presence records. there additional query executed twice per each such object: entry/exit detection event (e.g. when such list has serialized publishing rest api). plus automated mapping of generated in such way exitdetectionevent = null (a valid case when person entered did not exit) json kind of issue me here.
i guess define dao based on query joining these tables additional data bean - variation of presence entity bean. maybe there simpler way. so...
question 2: can done more effectively? suggestions appreciated...
jpa model is:
@entity @table(name = "locationsignal") public class locationsignal implements serializable { private static final long serialversionuid = 1l; @id @generatedvalue(strategy = generationtype.sequence) @column(name = "id") private long id; @column(name = "details") private string details; @onetomany(mappedby = "locationsignal", cascade = cascadetype.all, fetch = fetchtype.lazy) private list<detectionevent> detectioneventlist = new arraylist<>(); } @entity @table(name = "person") public class person implements serializable { private static final long serialversionuid = 1l; @id @generatedvalue(strategy = generationtype.sequence) @column(name = "id") private long id; @onetomany(mappedby = "person", cascade = cascadetype.all, fetch = fetchtype.lazy) private list<detectionevent> detectioneventlist = new arraylist<>(); @onetomany(mappedby = "person", cascade = cascadetype.all, fetch = fetchtype.lazy) private list<presence> presencelist = new arraylist<>(); public long getid() { return id; } } @entity @table(name = "building") public class building implements serializable { private static final long serialversionuid = 1l; @id @generatedvalue(strategy = generationtype.sequence) @column(name = "id") private long id; @onetomany(mappedby = "building", cascade = cascadetype.all, fetch = fetchtype.lazy) private list<presence> presencelist = new arraylist<>(); } @entity @table(name = "detectionevent") public class detectionevent implements serializable { private static final long serialversionuid = 1l; @id @manytoone() @joincolumn(name = "person_id", referencedcolumnname = "id") private person person; @id @manytoone() @joincolumn(name = "detectioneventhistory_id", referencedcolumnname = "id") private detectioneventhistory detectioneventhistory; @manytoone() @joincolumn(name = "locationsignal_id", referencedcolumnname = "id") private locationsignal locationsignal; public person getperson() { return person; } } @entity @table(name = "detectioneventhistory") public class detectioneventhistory implements serializable { private static final long serialversionuid = 1l; @id @generatedvalue(strategy = generationtype.sequence) @column(name = "id") private long id; @column(name = "timestamp") private timestamp timestamp; @onetomany(mappedby = "detectionevent", cascade = cascadetype.all, fetch = fetchtype.lazy) private list<detectionevent> detectioneventlist = new arraylist<>(); @onetomany(mappedby = "entrydetectioneventhistory", cascade = cascadetype.all, fetch = fetchtype.lazy) private list<presence> entrydetectioneventhistorylist = new arraylist<>(); @onetomany(mappedby = "exitdetectioneventhistory", cascade = cascadetype.all, fetch = fetchtype.lazy) private list<presence> exitdetectioneventhistorylist = new arraylist<>(); } @entity @table(name = "presence") public class presence implements serializable { private static final long serialversionuid = 1l; @id @manytoone() @joincolumn(name = "person_id", referencedcolumnname = "id") private person person; @id @manytoone() @joincolumn(name = "building_id", referencedcolumnname = "id") private building building; @id @manytoone() @joincolumn(name = "presencehistory_id", referencedcolumnname = "id") private presencehistory presencehistory; @manytoone() @joincolumn(name = "entry_detectioneventhistory_id", referencedcolumnname = "id") private detectioneventhistory entrydetectioneventhistory; @manytoone() @joincolumn(name = "exit_detectioneventhistory_id", referencedcolumnname = "id") private detectioneventhistory exitdetectioneventhistory; } @entity @table(name = "presencehistory") public class presencehistory implements serializable { private static final long serialversionuid = 1l; @id @generatedvalue(strategy = generationtype.sequence) @column(name = "id") private long id; @column(name = "timestamp") private timestamp timestamp; @onetomany(mappedby = "presencehistory", cascade = cascadetype.all, fetch = fetchtype.lazy) private list<presence> presencelist = new arraylist<>(); }

Comments
Post a Comment