java - How to persist two entities with JPA -
java - How to persist two entities with JPA -
i using jpa in webapp , can't figure out how persist 2 new entities relate each other. here example:
these 2 entities +-----------------+ +--------------------+ | consumer | | profilepicture | +-----------------+ +--------------------+ | id (pk) |---| consumerid (ppk+fk)| | username | | url | +-----------------+ +--------------------+the consumer has id , other values. profilepicture uses consumer's id it's own primary key , foreign key. (since profilepicture not exist without consumer , not every consumer has profilepicture)
i used netbeans generate entity classes , session beans (facades).
this how in shortconsumer.java
@entity @table(name = "consumer") @namedqueries({...}) public class consumer implements serializable { @id @generatedvalue(strategy = generationtype.identity) @basic(optional = false) @column(name = "id") private integer id; @basic(optional = false) @notnull @size(min = 1, max = 50) @column(name = "username") private string username; @onetoone(cascade = cascadetype.all, mappedby = "consumer") private profilepicture profilepicture; /* , basic getters , setters */ (...) }
profilepicture.java
@entity @table(name = "profilepicture") @xmlrootelement @namedqueries({...}) public class profilepicture implements serializable { @id @basic(optional = false) @notnull @column(name = "consumerid") private integer consumerid; @basic(optional = false) @notnull @size(min = 1, max = 255) @column(name = "url") private string url; @joincolumn(name = "consumerid", referencedcolumnname = "id", insertable = false, updatable = false) @onetoone(optional = false) private consumer consumer; /* , basic getters , setters */ (...) }
so when want create consumer profilepicture thought this:
profilepicture profilepicture = new profilepicture("http://www.url.to/picture.jpg"); // create image object consumer consumer = new consumer("john doe"); // create consumer object profilepicture.setconsumer(consumer); // set consumer in image (so jpa can take care relation consumerfacade.create(consumer); // facade classes persist consumer profilepicturefacade.create(profilepicture); // , when consumer persisted (and has id) persist image
my problem i tried in every combination jpa doesn't seem able link 2 entities on it's own. of time getting errors this:
ejb5184:a scheme exception occurred during invocation on ejb consumerfacade, method: public void com.me.db.resources.bean.consumerfacade.create(com.mintano.backendclientserver.db.resources.entity.consumer) (...) bean validation constraint(s) violated while executing automatic bean validation on callback event:'prepersist'. please refer embedded constraintviolations details.
as far understand problem, because profilepicture doesn't know id of consumer , thus, entities cannot persist.
the way ever worked, when persisting consumer first, setting it's id profilepicture , persisting picture:
profilepicture profilepicture = new profilepicture("http://www.url.to/picture.jpg"); // create image object consumer consumer = new consumer("john doe"); // create consumer object consumerfacade.create(consumer); // facade classes persist consumer profilepicture.setconsumerid(consumer.getid()); // set consumer's new id in image profilepicturefacade.create(profilepicture); // , when consumer persisted (and has id) persist image
however these 2 tables illustration , naturally database much more complex , setting ids manually seems inflexible , afraid of on complicating things. because can't persist entities in 1 transaction (which seems inefficient).
am doing right? or there another, more standard way?
edit: solutionas ftr suggested, 1 problem missing id
profilepicture table (i used consumer.id foreign , primary)..
the tables now:
+-----------------+ +--------------------+ | consumer | | profilepicture | +-----------------+ +--------------------+ | id (pk) |_ | id (pk) | | username | \_| consumerid (fk) | +-----------------+ | url | +--------------------+then alan hay told me always encapsulate add/remove relationships , can ensure correctness, did:
consumer.java
public void addprofilepicture(profilepicture profilepicture) { profilepicture.setconsumerid(this); if (profilepicturecollection == null) { this.profilepicturecollection = new arraylist<>(); } this.profilepicturecollection.add(profilepicture); }
since profilepicture has it's own id now, became onetomany relationship, each consumer can have many profile pictures. that's not intended @ first, can life :) hence can't set profilepicture consumer have add together collection of pictures (as above).
this additional method implemented , works. 1 time again help!
when persisting instance of non-owning side of relationship (that contains 'mappedby' , in case consumer) must always ensure both sides of relationship set have cascading work expected.
you should of course of study anyway ensure domain model correct.
consumer c = new consumer(); profilepicure p = new profilepicture(); c.setprofilepicture(p);//see implementation //persist c
consumer.java
@entity @table(name = "consumer") @namedqueries({...}) public class consumer implements serializable { @id @generatedvalue(strategy = generationtype.identity) @basic(optional = false) @column(name = "id") private integer id; @basic(optional = false) @notnull @size(min = 1, max = 50) @column(name = "username") private string username; @onetoone(cascade = cascadetype.all, mappedby = "consumer") private profilepicture profilepicture; public void setprofilepicture(profilepicture profilepicture){ //set both sides of relationship this.profilepicture = profilepicture; profilepicture.setconsumer(this); } }
always encapsulate add/remove relationships , can ensure correctness:
public class parent{ private set<child> children; public set<child> getchildren(){ homecoming collections.unmodifiableset(children); //no direct access:force clients utilize add/remove methods } public void addchild(child child){ child.setparent(this); children.add(child); } public class child(){ private parent parent; }
java jpa javabeans
Comments
Post a Comment