java - Replacing a full ORM (JPA/Hibernate) by a lighter solution : Recommended patterns for load/save? -
i'm developing new java web application , i'm exploring new ways (new me!) persist data. have experience jpa & hibernate but, except simple cases, think kind of full orm can become quite complex. plus, don't working them much. i'm looking new solution, closer sql.
the solutions i'm investigating :
but there 2 use cases i'm worrying solutions, compared hibernate. i'd know recommended patterns use cases.
use case 1 - fetching entity , accessing of associated children , grandchildren entities.
- let's have
person
entity.- this
person
has associatedaddress
entity.- this
address
has associatedcity
entity.- this
city
entity hasname
property.
- this
- this
- this
the full path access name of city, starting person entity, :
person.address.city.name
now, let's load person entity personservice
, method :
public person findpersonbyid(long id) { // ... }
using hibernate, entities associated person
lazily loaded, on demand, possible access person.address.city.name
, sure have access property (as long entities in chain not nullable).
but using of 3 solutions i'm investigating, it's more complicated. solutions, recommended patterns take care of use case? upfront, see 3 possible patterns:
all required associated children , grandchildren entities eagerly loaded sql query used.
but issue see solution there may other code needs access other entities/properties paths
person
entity. example, maybe code need accessperson.job.salary.currency
. if want reusefindpersonbyid()
method have, sql query need load more information! not associatedaddress->city
entity associatedjob->salary
entity.now if there 10 other places need access other information starting person entity? should eagerly load all potentially required information? or maybe have 12 different service methods load person entity? :
findpersonbyid_simple(long id) findpersonbyid_withadresscity(long id) findpersonbyid_withjob(long id) findpersonbyid_withadresscityandjob(long id) ...
but everytime use
person
entity, have know has been loaded , hasn't... quite cumbersome, right?in
getaddress()
getter method ofperson
entity, there check see if address has been loaded and, if not, lazily load it? used pattern in real life applications?are there other patterns can used make sure can access entities/properties need loaded model?
use case 2 - saving entity , making sure associated , modified entities saved.
i want able save person
entity using personservice
's method :
public void saveperson(person person) { // ... }
if have person
entity , change person.address.city.name
else, how can make sure city
entity modifications persisted when save person
? using hibernate, can easy cascade save operation associated entities. solutions i'm investigating?
should use kind of dirty flag know associated entities have saved when save person?
are there other known patterns useful deal use case?
update : there a discussion question on jooq forum.
this kind of problem typical when not using real orm, , there no silver bullet. simple design approach worked me (not big ) webapp ibatis (mybatis), use 2 layers persistence:
a dumb low-level layer: each table has java class (pojo or dto), fields maps directly table columns. have
person
tableaddress_id
field pointsadress
table; then, we'd havepersondb
class,addressid
(integer) field; have nopersondb.getadress()
method, plainpersondb.getadressid()
. these java classes are, then, quite dumb (they don't know persistence or related classes). correspondingpersondao
class knows how load/persist object. layer easy create , maintain tools ibatis + ibator (or mybatis + mybatisgenerator).a higher level layer contains rich domain objects: each of these typically graph of above pojos. these classes have intelligence loading/saving graph (perhaps lazily, perhaps dirty flags), calling respective daos. important thing, however, these rich domain objects not map one-to-one pojo objects (or db tables), rather domain use cases. "size" of each graph determined (it doesn't grow indefinitely), , used outside particular class. so, it's not have 1 rich
person
class (with indeterminate graph of related objects) used several use cases or service methods; instead, have several rich classes,personwithaddreses
,personwithalldata
... each 1 wraps particular well-limited graph, own persistence logic. might seem inefficient or clumsy, , in context might be, happens use cases when need save full graph of objects limited.additionally, things tabular reports, (specific selects return bunch of columns displayed) you'd not use above, straight , dumb pojo's (perhaps maps)
see related answer here
Comments
Post a Comment