java - JPA Foreign Key constraint violation cannot insert Null -


i have simple user , roles entities 1 many mapping. 1 user many roles. getting error when try save user entity. setting role object user before calling persist.

below snap shot of entities.

user:

package com.petpe.ejbadmin.entity;  import java.io.serializable; import java.util.date; import java.util.set;  import javax.annotation.generated; import javax.persistence.basic; import javax.persistence.cascadetype; import javax.persistence.column; import javax.persistence.entity; import javax.persistence.fetchtype; import javax.persistence.generatedvalue; import javax.persistence.generationtype; import javax.persistence.id; import javax.persistence.namedqueries; import javax.persistence.namedquery; import javax.persistence.onetomany; import javax.persistence.table; import javax.persistence.temporal; import javax.persistence.temporaltype; import javax.validation.constraints.notnull; import javax.validation.constraints.size; import javax.xml.bind.annotation.xmlrootelement; import javax.xml.bind.annotation.xmltransient;   @entity @table(name = "users") @xmlrootelement @namedqueries({     @namedquery(name = "user.findall", query = "select u user u"),     @namedquery(name = "user.findbyusernameandpassword", query = "select u user u u.username = :username , u.password = :password"),     @namedquery(name = "user.findbyuserfirstname", query = "select u user u u.userfirstname = :userfirstname"),     @namedquery(name = "user.findbyuserlastname", query = "select u user u u.userlastname = :userlastname"),     @namedquery(name = "user.findbyphonenumber", query = "select u user u u.phonenumber = :phonenumber"),     @namedquery(name = "user.findbyemail", query = "select u user u u.email = :email"),     @namedquery(name = "user.findbyerpid", query = "select u user u u.erpid = :erpid"),     @namedquery(name = "user.findbybuyerid", query = "select u user u u.buyerid = :buyerid"),     @namedquery(name = "user.findbycreateddate", query = "select u user u u.createddate = :createddate"),     @namedquery(name=  "user.findbyfirstletter",query="select u user u join fetch u.roleset ur lower(u.userfirstname) :firstname"),     @namedquery(name=  "user.findallusers",query="from user u join fetch u.roleset ur")}) public class user implements serializable {     private static final long serialversionuid = 1l;     @id     @generatedvalue(strategy=generationtype.identity)     @basic(optional = true)     @column(name = "user_id")     private integer userid;     @size(max = 120)     @column(name = "username")     private string username;     @size(max = 60)     @column(name = "userfirstname")     private string userfirstname;     @size(max = 60)     @column(name = "userlastname")     private string userlastname;     @size(max = 50)     @column(name = "password")     private string password;     @size(max = 20)     @column(name = "phonenumber")     private string phonenumber;     // @pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="invalid email")//if field contains email address consider using annotation enforce field validation     @size(max = 50)     @column(name = "email")     private string email;     @size(max = 250)     @column(name = "erpid")     private string erpid;     @size(max = 250)     @column(name = "buyerid")     private string buyerid;     @basic(optional = false)     @notnull     @column(name = "created_date")     @temporal(temporaltype.date)     private date createddate;     @onetomany(cascade = cascadetype.all, mappedby = "user", fetch = fetchtype.lazy)     private set<role> roleset;      public user() {     }      public user(integer userid) {         this.userid = userid;     }      public user(integer userid, date createddate) {         this.userid = userid;         this.createddate = createddate;     }      public integer getuserid() {         return userid;     }      public void setuserid(integer userid) {         this.userid = userid;     }      public string getusername() {         return username;     }      public void setusername(string username) {         this.username = username;     }      public string getuserfirstname() {         return userfirstname;     }      public void setuserfirstname(string userfirstname) {         this.userfirstname = userfirstname;     }      public string getuserlastname() {         return userlastname;     }      public void setuserlastname(string userlastname) {         this.userlastname = userlastname;     }      public string getpassword() {         return password;     }      public void setpassword(string password) {         this.password = password;     }      public string getphonenumber() {         return phonenumber;     }      public void setphonenumber(string phonenumber) {         this.phonenumber = phonenumber;     }      public string getemail() {         return email;     }      public void setemail(string email) {         this.email = email;     }      public string geterpid() {         return erpid;     }      public void seterpid(string erpid) {         this.erpid = erpid;     }      public string getbuyerid() {         return buyerid;     }      public void setbuyerid(string buyerid) {         this.buyerid = buyerid;     }      public date getcreateddate() {         return createddate;     }      public void setcreateddate(date createddate) {         this.createddate = createddate;     }      @xmltransient     public set<role> getroleset() {         return roleset;     }      public void setroleset(set<role> roleset) {         this.roleset = roleset;     }      @override     public int hashcode() {         int hash = 0;         hash += (userid != null ? userid.hashcode() : 0);         return hash;     }      @override     public boolean equals(object object) {         // todo: warning - method won't work in case id fields not set         if (!(object instanceof user)) {             return false;         }         user other = (user) object;         if ((this.userid == null && other.userid != null) || (this.userid != null && !this.userid.equals(other.userid))) {             return false;         }         return true;     }      @override     public string tostring() {         return "[ userid=" + userid + " ]";     }  } 

role:

/* * change license header, choose license headers in project properties. * change template file, choose tools | templates * , open template in editor. */

package com.petpe.ejbadmin.entity;  import java.io.serializable;  import javax.persistence.basic; import javax.persistence.column; import javax.persistence.entity; import javax.persistence.fetchtype; import javax.persistence.generatedvalue; import javax.persistence.generationtype; import javax.persistence.id; import javax.persistence.joincolumn; import javax.persistence.manytoone; import javax.persistence.namedqueries; import javax.persistence.namedquery; import javax.persistence.table; import javax.validation.constraints.notnull; import javax.validation.constraints.size; import javax.xml.bind.annotation.xmlrootelement;   @entity @table(name = "user_roles") @xmlrootelement public class role implements serializable {     private static final long serialversionuid = 1l;     @id     @generatedvalue(strategy=generationtype.identity)     @basic(optional = false)     @column(name = "roleid")     private integer roleid;     @basic(optional = false)     @notnull     @size(min = 1, max = 30)     @column(name = "rolename")     private string rolename;     @joincolumn(name = "user_id", referencedcolumnname = "user_id")     @manytoone( fetch = fetchtype.lazy)     private user user;      public role() {     }      public role(string rolename) {         this.rolename = rolename;     }      public role(integer roleid, string rolename) {         this.roleid = roleid;         this.rolename = rolename;     }      public user getuser() {         return user;     }      public void setuser(user user) {         this.user = user;     }      public integer getroleid() {         return roleid;     }      public void setroleid(integer roleid) {         this.roleid = roleid;     }      public string getrolename() {         return rolename;     }      public void setrolename(string rolename) {         this.rolename = rolename;     }        @override     public int hashcode() {         int hash = 0;         hash += (roleid != null ? roleid.hashcode() : 0);         return hash;     }      @override     public boolean equals(object object) {         // todo: warning - method won't work in case id fields not set         if (!(object instanceof role)) {             return false;         }         role other = (role) object;         if ((this.roleid == null && other.roleid != null) || (this.roleid != null && !this.roleid.equals(other.roleid))) {             return false;         }         return true;     }      @override     public string tostring() {         return "[ roleid=" + roleid + " ]";     }  } 

error:

1.cannot insert value null column 'user_id', table 'pedb.pedb.user_roles'; column not allow nulls. insert fails. 2.could not insert: [com.petpe.ejbadmin.entity.role] 3.org.hibernate.exception.constraintviolationexception: not insert: [com.petpe.ejbadmin.entity.role] 4.javax.persistence.persistenceexception: org.hibernate.exception.constraintviolationexception: not insert: [com.petpe.ejbadmin.entity.role] 

setting , persisting code:

public boolean addormodifyuser(useradmindto udato) {          user usr=this.populateuserobj(udato);         pet_em.persist(usr);          return true;     }  public user populateuserobj(useradmindto udto)     {         user usr=new user();          usr.setbuyerid(udto.getbuyerid());         usr.setcreateddate(new date());         usr.setemail(udto.getemail());         usr.seterpid(udto.geterpid());         usr.setpassword(udto.getpassword());         usr.setphonenumber(udto.getphonenumber());         usr.setuserfirstname(udto.getfirstname());         usr.setuserlastname(udto.getlastname());         usr.setusername(udto.getusername());         for(role r: udto.getrole())         {             set<role> roleset=new hashset<>();             roleset.add(r);                  usr.setroleset(roleset);         }         return usr;     } 

layout of table:

enter image description here

so have not null constraint on user_id inside roles tables. when persisting (even cascading relationships), foreign key (or entity relationship) not automagically set itself.

most when creating role, did not set user, when persisting, provider has no idea user_id is, tries set null in db, violation of db schema.

all need set user each role

set<role> roleset=new hashset<>(); for(role r: udto.getrole()) {     r.setuser(usr);   // <------     roleset.add(r);      } usr.setroleset(roleset); 

also notice set created outside loop

and...but...wait...

you're not out woods yet. above solve error, still have problem. it's subtle , lead hard find bugs.

you have role id being generated.

@id @generatedvalue(strategy=generationtype.identity) private integer roleid; 

so don't set when creating role

set<role> roles = new hashset<>(); role userrole = new role("user"); userrole.setuser(user); roles.add(userrole); role coolrole = new role("cool_guy"); coolrole.setuser(user); roles.add(coolrole); user.setroleset(roles); 

doesn't problem, bug in hashcode

@override public int hashcode() {     int hash = 0;     hash += (roleid != null ? roleid.hashcode() : 0);     return hash; } 

the hashcode consists of roleid. don't set roleid because supposed generated. when add roles set, have same hashcode, add 1 role set, objects in set cannot have same hashcode.

to fix this, can change hashcode include rolename.

while testing, had netbeans generate hashcode , equals. here's result.

@override public int hashcode() {     int hash = 7;     hash = 31 * hash + objects.hashcode(this.roleid);     hash = 31 * hash + objects.hashcode(this.rolename);     return hash; }  @override public boolean equals(object obj) {     if (obj == null) {         return false;     }     if (getclass() != obj.getclass()) {         return false;     }     final role other = (role) obj;     if (!objects.equals(this.roleid, other.roleid)) {         return false;     }     if (!objects.equals(this.rolename, other.rolename)) {         return false;     }     return true; } 

that should fix bug.


Comments

Popular posts from this blog

resizing Telegram inline keyboard -

command line - How can a Python program background itself? -

php - "cURL error 28: Resolving timed out" on Wordpress on Azure App Service on Linux -