PersistenceException occured : org.hibernate.exception.ConstraintViolationException: could not insert: [models.User] - java

I have got this exception!!
here is my model class
#Entity
public class User extends Model {
#OneToMany(mappedBy="email", cascade=CascadeType.ALL)
public List<Photo> photo;
#Email
#Required
#Unique
public String email;
#Required
public String passwordHash;
#Required
public String education;
#Required
public String fname;
#Required
public String lname;
#Required
public Date dob;
#Required
public String gender;
#Required
public String country;
#Required
public Long phone;
#Required
public String status;
#Required
public String jobtitle;
#Required
public String company;
#Required
public String industry;
#Required
public Date addDate;
public String needConfirmation;
public User(String email, String password, String fname,
String lname, Date dob, String gender, String country,
Long phone, String status, String education, String jobtitle, String company, String industry) {
//all initialization here
}
}
can you please tell me where I am going wrong
playframework× 2289
this is my photo class, and please tell me how can I allow JPA to generate my database
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package models;
import controllers.Users;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import play.db.jpa.Model;
/**
*
* #author nPandey
*/
#Entity
public class Photo extends Model{
public String photoname;
#ManyToOne
public User email;
public String owner;
public Photo(){
}
public Photo(User email, String photo){
this.photoname=photo;
this.email=email;
this.owner=email.email;
}
}

Check that your entity isn't missing any required fields when it's being persisted / updated. Also check what constraints are set on the User-table in the DB (unique keys, foreign keys, non nulls...).

Your mappedBy value makes little sense. It is used on the passive end of a bi-directional association. In those cases it points to the attribute on the other class on the other side of the relationship. You are pointing it to one of the attributes of the User class. Perhaps your Photo class has a email attribute, but is that of type User ( i am guessing not). So if this is a bi-directional association, set the mappedBy value to the attribute on Photo having the corresponding #ManyToOne "back" to the User. If it is a unidirectional association, remove the mappedBy and perhaps use #JoinColumn to use the foreign key mapping strategy of unidirectional one-to-many

I was facing same issue and it got resolved by changing relationship related notation from OneToMany to ManyToMany. In My case there was ManyToMany relation between Job and Person Table and I was trying to add same jobList to multiple person object in a loop.
The problem was with the annotation used in Person Entity class for Job Entity:
#ManyToMany // Changed from OneToMany to ManyToMany
private List<Job> jobList = new ArrayList<Job>();

Try editing the code as below -
In User Model
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
public List<Photo> photos;
In Photo Model
#ManyToOne
#NotFound(action = NotFoundAction.IGNORE)
#JoinColumn(name = "email", nullable = false, insertable = false, updatable = false)
public User user;
Check this for reference - http://en.wikibooks.org/wiki/Java_Persistence/OneToMany#Example_of_a_OneToMany_relationship_and_inverse_ManyToOne_annotations

Related

Mapping entities in JPA/Hibernate without adding additional fields (just by using ids)

I'm trying to map those three entities to each other without adding any additional fields to any of them. They should only contain the fields that already exist. I'm also trying to only get columns in the tables that represent the currently existing entity fields- and no additional columns.
#Entity
public class Order {
#Id
private Integer orderId;
private String title;
private Customer customer;
private List<Comment> comments;
}
#Entity
public class Customer {
#Id
private Integer customerId;
private String name;
}
#Entity
public class Comment {
#Id
private Integer commentId;
private Integer orderId;
private String details;
}
My understanding is that I can't simply use #OneToOne, #OneToMany and #ManyToOne mappings, because neither Customer nor Comment has a reference to Order . I'm trying to somehow reference the ids of Customer and Comment directly from Order.
I've tried using #MapsId and #JoinColumn but either I don't know how to properly use them, or they don't do what I think they do.
Is this task at all possible? If so, how to map them to each other?
For the reference to Comment you must use #JoinColum
The Customer reference assumes that there is a customer_id on the order table.
#Entity
public class Order {
#Id
private Integer orderId;
private String title;
#ManyToOne
#JoinColumn(name = "customer_id")
private Customer customer;
#OneToMany
#JoinColumn(name = "comment_id")
private List<Comment> comments;
}

The embedded key is not showing in the forms

I'm using Spring Roo 2.0.0.RC1.
I have a table that has a composite key of two strings. So I defined the PersonId entity :
#RooToString
#Embeddable
#RooSerializable
#RooIdentifier(dbManaged = true)
public class PersonId {
private String postalCode;
#NotNull
private String city;
}
Then I created a Person entity with PersonId as an identifier type :
#RooJavaBean
#RooToString
#RooJpaEntity
#RooEquals(isJpaEntity = true)
public class Person {
#EmbeddedId
private PersonId id;
#Version
private Integer version;
private String address;
#NotNull
private String currentPosition;
}
The project compiles fine, but the problem is that the PersonId's fields don't show on the CRUD form.
How can I make the embedded composite key show in the CRUD form ?

How to join three entities in one table using spring jpa?

I am trying to join three entities (table) using spring-jpa into one table using Many-To-Many relationship.
Three classes are :
1] User
2] Resource
3] Privilege
And I want to combine these three entities into one User_Resource_Privilege table
User Entity
package com.****.acl.domain;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
#Entity
public class User {
#Id #GeneratedValue(generator="system-uuid")
#GenericGenerator(name="system-uuid", strategy = "uuid")
#Column(name="user_id", nullable=false, length=40)
private String userId;
#Column(name="user_name", nullable=false, length=45)
private String userName;
#Column(name="first_name", nullable=true, length=45)
private String firstName;
#Column(name="last_name", nullable=true, length=45)
private String lastName;
#Column(name="email", nullable=true, length=50)
private String email;
public User(){
}
public User(String userName, String firstName, String lastName, String email) {
this.userName = userName;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
getter and setters .......
}
Resource Entity
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.*;
import org.hibernate.annotations.GenericGenerator;
#Entity
public class Resource {
#Id #GeneratedValue(generator="system-uuid")
#GenericGenerator(name="system-uuid", strategy = "uuid")
#Column(name="resource_id", nullable=false, length=40)
private String resourceId;
#Column(name="resource_name", nullable=false, length=45)
private String name;
#Column(name="resource_type", nullable=false, length=45)
private String type;
public Resource(){
}
public Resource(String name, String type) {
this.name = name;
this.type = type;
}
getter and setter ......
}
Privilege Entity
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.*;
import org.hibernate.annotations.GenericGenerator;
#Entity
public class Privilege {
#Id #GeneratedValue(generator="system-uuid")
#GenericGenerator(name="system-uuid", strategy = "uuid")
#Column(name="privilege_id", nullable=false, length=40)
private String privilegeId;
#Column(name="resource_name", nullable=false, length=45)
private String name;
#Column(name="resource_description", nullable=true, length=45)
private String description;
public Privilege(){
}
getters and setters ....
}
Now I want to create one table by joining all the three entities described above.
The join in ER diagram:
Can someone please help me in joining these three tables using Many-To-Many relationship and let me know how to achieve this using spring-jpa and REST ?
Also it will be great if you please explain how to insert data in this "User_Resource_Privilege" table using REST/curl command ?
What you could do is make an embeddable ID and wrap it with the class. You can afterwards even expand this wrapper class to hold other fields.
java geeks example of embedded id
You would get something like
#Embeddable
public class EmbeddedIdClass implements Serializable {
private String userId;
private String resourceId;
private String privilegeId;
// constructors, getters and setters, equals, etc
}
#Entity
public class Wrapper {
#EmbeddedId
private EmbeddedIdClass id;
// constructors, etc
}
Instead of just using the strings in this example, you should use the complete objects and let hibernate (or something like it) do it's stuff. It should only take the id's into the database and do it's magic itself.
edit:
Just wanting to insert the id's as values, but keeping relationships would look something like this
#Entity
public class Wrapper {
#Id
private String id;
private User user;
private Resource resource;
private Privilege privilege;
// constructors
public Wrapper(final User user, final Resource resource, final Privilege privilege) {
this.user = user;
this.resource = resource;
this.privilege = privilege;
}
}

Retrieve logged user object and save it as a foreign key

While saving some data from the form I also need to add FK to the Record table. FK is User.Id.
I know how to save data from the input field on the form, but how can I set FK (int value) to this:
#ManyToOne
#JoinColumn(name = "id")
#Cascade({CascadeType.ALL})
private User user;
Is there some way to retrieve object which relates to logged user and make something like this: record.setUser(user)?
I've googled it but I didn't manage to find how to achive this.
This is my entity class.
#Entity
public class Record implements java.io.Serializable{
#Id
#GeneratedValue
private int recordId;
private String recordName;
private String recordComment;
private Date recordDate;
private Integer price;
#ManyToOne
#JoinColumn(name = "userId", insertable = true, updatable = false)
#Cascade({CascadeType.ALL})
private User user;
......
}
#Entity
#Table(name = "system_user")
public class User implements java.io.Serializable{
#Id
#GeneratedValue
private int userId;
#NotEmpty
#Email
private String email;
#Size(min=2, max=30)
private String name;
private String enabled;
#NotEmpty
private String password;
private String confirmPassword;
#Enumerated(EnumType.STRING)
#Column(name = "user_role")
private Role role;
#OneToMany(fetch = FetchType.EAGER,mappedBy = "user", orphanRemoval=true)
#Cascade({CascadeType.ALL})
private List<Record> records;
public void addToRecord(Record record) {
record.setUser(this);
this.records.add(record);
}
....
}
This is how I save data to DB:
#RequestMapping(value = "/protected/add", method = RequestMethod.POST)
public String addCost (#ModelAttribute("record") Record record,HttpSession session){
User user = userManager.getUserObject(userManager.getUserId(session.getAttribute("currentUser").toString()));
user.addToRecord(record);
recordService.addRecord(record);
return "redirect:/protected/purse";
}
DAO:
public void addRecord(Record record) {
sessionFactory.getCurrentSession().save(record);
}
UPDATE: problem was partially solved, code above works fine for me.
You also need to create User object and set the user object in a Record object using the below code
record.setUser(userObj);
and user foreign key will be automatically saved in database.

OneToOne relationship for a non primary key column

I'm having a problem when I query an entity who has a OneToOne relationship with another one. This is the scenario:
Database tables:
create table people (
id decimal(10,0) NOT NULL,
email varchar(512) NOT NULL
);
create table users (
email varchar(512) NOT NULL
);
Test data:
insert into users (email) values ('jhon#domain.com');
insert into users (email) values ('mary#domain.com');
insert into people (id, email) values (1, 'jhon#domain.com');
insert into people (id, email) values (2, 'mary#domain.com');
Entities:
#Entity(name = "people")
public class Person implements Serializable {
#Column
#Id
private long id;
#Column
private String email;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
#Entity(name = "tbl_users")
public class User implements Serializable {
#Id
private String email;
#OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
#JoinColumn(name = "email", referencedColumnName = "email")
private Person person;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Invocation:
...
User user = entityManager.find(User.class, "jhon#domain.com");
...
After de invocation, the hibernate's logs shows:
select user1_.email as email2_0_, person2_.id as id1_1_, person2_.email as email1_1_
from users user1_ left outer join people person2_ on user1_.email=person2_.id
where user1_.email=?
As you can see, the join is wrong because is comparing users.email with people.id (user1_.email=person2_.id), so it returns an User without its corresponding Person.
Any ideas about how can I fix it?
Thanks a lot !!
Strictly speaking, the JPA specification does not allow references to non-primary key columns. It may work in some JPA implementations, but it's not proper.
However, i think you can do this by making the relationship bidirectional, and owned by the side with the non-primary key:
#Entity
public class Person {
#Id
private long id;
#OneToOne
#JoinColumn(name = "email")
private User user;
public String getEmail() {
return user.getEmail();
}
public void setEmail(String email) {
// left as an exercise for the reader
}
}
#Entity
public class User {
#Id
private String email;
#OneToOne(mappedBy = "user")
private Person person;
}
I haven't actually tried that, though, so caveat hackor.
I think you should rethink your datamodel. The relationship between User and Person looks more like one of Inheritance.
For the issue with your mappings as they stand see here for some further disussion:
JPA providers: why do relationships/FKs to non-PK columns work in Hibernate and EclipseLink?
Does the JPA specification allow references to non-primary key columns?

Categories