how to use hibernate annotations OnetoOne in springMvc? - database

I'm working with spring MVC``Spring security hibernate
I've created 2 tables in the database , this the schema:
create table user(
id int(10),
name VARCHAR(30) NOT NULL,
address VARCHAR(30) NOT NULL,
PRIMARY KEY (id)
);
create table compte(
id int(10),
login VARCHAR(30) NOT NULL,
password VARCHAR(30) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (id) REFERENCES user( id)
);
I'm developing a web application for users managements, the administrator add user's informations and submit (data from the first form is inserted into the userdatabase) and then in an other jsp he adds the authentication data for this user and submit ( here data is inserted into the second database compte )
the form in the jsp page that inserts into user's table is done correctly when it's not joined to any other table .
But when I tried to use hibernate annotations in my application and join the two tables user and compte I have errors :
Caused by: org.hibernate.AnnotationException: Unknown mappedBy in: com.package.domain.User.compte, referenced property unknown: com.package.domain.Compte.User
user.java :
#Entity
#Table(name = "user")
public class User {
#Id
#Column(name="id")
private int id;
#Column(name="name")
private String name;
#Column(name="address")
private String address;
#OneToOne(mappedBy="User", cascade=CascadeType.ALL)
private Compte compte;
//getters and setters
compte.java :
#Entity
#Table(name = "COMPTE")
public class Compte {
#Id
#GeneratedValue
#Column(name = "id")
private int id;
#Column(name = "login")
private String login;
#Column(name = "password")
private String password;
#OneToOne
#PrimaryKeyJoinColumn
private User user;
//getters and setters
I don't know how should I insert comptedata into the second table ? how it will recognize that the login and the password correspond to the user's id just inserted.
PS : i've created 2 tables in the database to use the second for authentication in spring security if my database design is incorrect please tell me :)

Firstly, you need to specify not a class name (User), but a property name (user) in the mappedBy
#OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
private Compte compte;
In my opinion It will be better to associate Compte to the User by an additional foreign key and I would like to have login and password in the User table.
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue
#Column(name = "f_id")
private int id;
#Column(name = "f_login")
private String login;
#Column(name = "f_password")
private String password;
#OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
private Compte compte;
}
#Entity
#Table(name = "comptes")
public class Compte {
#Id
#GeneratedValue
#Column(name = "f_id")
private int id;
#OneToOne
#JoinColumn(name = "fk_user")
private User user;
#Column(name = "f_name")
private String name;
}

Related

How to update a List of Users in the User class Spring Boot

I have a Java User class, a user can have friends (List<User>). By default, Hibernate create two tables : USER and USER_FRIENDS(USER_ID,FRIENDS_ID)
The problem is when I change friends in my code and that I save(user), spring add the new friends but don't remove in the database the friends removed from the array list.
#Entitypublic class User implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String pseudo;
private String password;
private String email;
private Gender gender;
#Lob
private byte[] avatar;
private String description;
private Date birthdate;
#ManyToMany(cascade = CascadeType.ALL)
private List<Game> favoriteGames = new ArrayList<>();
#OneToMany( cascade = CascadeType.ALL)
private List<User> friends = new ArrayList<>();
I tried #ManyToMany, #OneToMany, cascade = CascadeType.ALL
Basically, first I would advise that you take special care with your equals and hashCode implementation in your entities. You did not show us that, but it should be something like this in your User.java:
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof User)) {
return false;
}
User other = (User) o;
return id != null && id.equals(other.getId());
}
#Override
public int hashCode() {
return getClass().hashCode();
}
Those are very important, especially when working with entities in collections.
Secondly, a connection between a User and his Friends (other Users) should be modeled as Many-to-Many, because:
every user can be a friend to MANY of other users
every user can have any number of friends, in other words MANY friends
And I would model this connection like this:
#ManyToMany
#JoinTable(name = "user_friends", joinColumns = #JoinColumn(name = "user_id"),
inverseJoinColumns = #JoinColumn(name = "friend_user_id"))
private Set<User> friends = new HashSet<>();

Hibernate cascade parent child when using sql server spatial dialect

I am using spring boot data jpa with SQLServer and spatial dialect as below:
spring.jpa.properties.hibernate.dialect=org.hibernate.spatial.dialect.sqlserver.SqlServer2008SpatialDialect
Parent Class:
#Entity
#Table(name = "users", schema = "dbo")
public class User {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
#JoinTable(name = "users_roles",
joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "role_id", referencedColumnName = "id"))
private Collection<Role> roles = new ArrayList<>();
}
Child Class:
#Entity
#Table(name = "roles", schema = "dbo")
public class Role {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#ManyToMany(mappedBy="roles", cascade = {CascadeType.ALL})
private Collection<User> users = new ArrayList<>();
}
on saving user:
u.setRoles(roles);
userRepository.save(u);
but alyways get user_id equals zero on table users_roles
please help
Note that SpatialDialect is needed to manage spatial data on other entities.

Bridge table primary as foreign key in another table (JPA)

I'm designing a student enrollment database
Student-Table
student_id (pk)
//other attributes
Course-Table
course_id (pk)
//other attributes
Student_course-Table
student_course_id(pk)
course_id (fk)
student_id (fk)
Lectrue-Table
lecture_id(pk)
student_course_id(fk - > student_course table)
// other attributes
Basically I want to store which student is enrolled to which course and has attend how many lectures for that particular course.
Q1 ) Is this design correct? Should I use primary key of Bridge table as foreign key in another table.
Q2 ) I did manyToMany mapping between student <-> course and oneToMany between student_course <-> lecture and got the following error :
org.hibernate.MappingException: Foreign key must have same number of columns as the referenced primary key
Any idea how to proceed?
//UPDATE Entity class
#Entity
#Table(name = "STUDENT")
public class Student implements Serializable {
#Id
#Column(name = "STUDENT_ID")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#ManyToMany(mappedBy = "students" ,cascade = CascadeType.ALL)
#MapKey(name = "courseName")
private Map<String, Course> courses;
}
#Entity
#Table(name = "COURSE", uniqueConstraints = #UniqueConstraint(columnNames = {"COURSE_NAME"}))
public class Course implements Serializable {
#Id
#Column(name = "COURSE_ID")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "STUDENT_COURSE", joinColumns = {
#JoinColumn(name = "COURSE_ID") }, inverseJoinColumns = {
#JoinColumn(name = "STUDENT_ID") })
private Set<Student> students;
#Column(name = "COURSE_NAME")
private String courseName;
}
#Entity
#Table(name = "LECTURE")
public class Lecture {
#Id
#Column(name = "LECTURE_ID")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "STUDENT_COURSE_ID")
private StudentCourse studentCourse;
}
#Entity
#Table(name = "STUDENT_COURSE")
public class StudentCourse {
#Id
#Column(name = "STUDENT_COURSE_ID")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "STUDENT_ID")
private Long studentId;
#Column(name = "COURSE_ID")
private Long courseId;
#OneToMany(mappedBy = "studentCourse")
private Set<Lecture> lectures = new HashSet<Lecture>();
}

Updating multiple tables when saving entity Spring MVC Angular

I have a problem with saving entity with references to database using
Spring MVC and AngularJS.
My entities:
Entity
#Table(name = "comment")
public class Comment {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name = "id", nullable = false)
private Long id;
#Column(name = "creation_date", nullable = false)
private Date creationDate;
#Column(name = "comment", nullable = false)
private String comment;
#ManyToOne
#JoinColumn(name = "article", nullable = false)
private Article article;
#ManyToOne
#JoinColumn(name = "user", nullable = false)
private User user;
}
#Entity
#Table(name = "article")
public class Article {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", nullable = false)
private Long id;
#ManyToOne
#JoinColumn(name="user", nullable=false)
private User user;
...
}
How can I save new Article but at the same time add new entity to Comment table?
How can two updates be performed in one transaction?
How sholud I connect request from angular with controller, and how sholud they look?
Angular:
$http({
url : ..../new,
method : POST,
data : ?
})
#RestController
#RequestMapping(value = "/new", method = RequestMethod.POST)
public Article addArticle(#RequestBody Article article, ?) {
article.setId(null);
return articleService.save(article);
//but how to save comment?
}
Thank You!

hibernate criteria if collection contains collection

I have a Priv class
#Entity
#Table(name = "PK_PRIVS", schema = "dbo")
public class Priv implements java.io.Serializable{
private static final long serialVersionUID = 1L;
private String code;
private String name;
private String description;
private PrivType type;
//...
}
and a Report class which has many to many relation with Priv and contains Set of associated Privs - privs.
#Entity
#Table(name = "REPORT", schema = "dbo")
public class Report implements java.io.Serializable {
//...
private Set<Priv> privs = new HashSet<Priv>(0);
//...
#JsonIgnore
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "REPORT_PK_PRIVS", schema = "dbo", joinColumns = { #JoinColumn(name = "REPORT_ID") }, inverseJoinColumns = { #JoinColumn(name = "PK_PRIVS_CODE") })
public Set<Priv> getPrivs() {
return this.privs;
}
public void setPrivs(Set<Priv> privs) {
this.privs = privs;
}
}
Now I have a Set of Strings, which are codes of Priv classes (code is Primary Key in Priv).
Set<String> privsCodesSet; //set of codes of Priv classes
I need a criterion which allow me to find that Reports, which all codes from its Priv set contains in privsCodesSet. For example if I have privsCodeSet = {"code1", "code2"}
Report with privs with codes {"code1"" should be in result, but
Report with privs with codes {"code1", "code2", "code3"} should not.
I also have class which is join of Priv and Report, but I'm not sure if it's help.
This code should work
Criteria reportPrivCriteria = currentSession()
.createCriteria( Report.class, "r");
reportPrivCriteria.createAlias("privs", "p");
reportPrivCriteria.add(Restrictions.in(p.code, privsCodeSet));
Do you have something like this on your Priv class?
private Set<Report> reports;
// ...
#ManyToMany(mappedBy="privs")
public Collection<Report> getReports() {
return reports;
}

Resources