I want to join two models, both are using org.hibernate.id.UUIDGenerator for primary key.
But on startup, I get the following error:
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error
executing DDL "alter table user_role add constraint
FK5scdquo6f12cpstqai86x4biw foreign key (roles_role_id) references
role (role_id)" via JDBC Statement
Do you know, what I'm doing wrong?
My code:
User Model:
#Entity
#Table
public class User implements Serializable {
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
#Column(name = "user_id", columnDefinition = "VARCHAR(255)")
private String userId;
#Column(name = "name")
private String name;
#JoinTable(name = "user_role", joinColumns = #JoinColumn(name = "userId"), inverseJoinColumns = #JoinColumn(name = "roleId"))
#ManyToMany
private List<Role> roles;
public User(){
this.roles = new ArrayList<>();
}
// Getter & Setter
}
Role Model:
#Entity
#Table
public class Role implements Serializable {
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
#Column(name = "role_id", columnDefinition = "VARCHAR(255)")
private String roleId;
#Column(name = "role_name")
private String name;
#Column(name = "description")
private String description;
#ManyToMany(mappedBy = "roles")
private List<User> users;
public Role(){
this.users = new ArrayList<>();
}
// Getter & Setter
}
User DAO:
public interface UserDAO extends JpaRepository<User, String > {
}
Role DAO:
public interface RoleDAO extends JpaRepository<Role, String > {
}
Your join column should have a name similar to the column name and not the model variable name. In your case you should use
joinColumns = #JoinColumn(name = "user_id")
and
inverseJoinColumns = #JoinColumn(name = "role_id"))
NOT
joinColumns = #JoinColumn(name = "userId")
and
inverseJoinColumns = #JoinColumn(name = "roleId"))
Also do this for all join columns
Related
I am working on a project, trying to create an AudioBook website. I am stuck on this part and i cant find answers on the internet.
The problem is when i get user, and list of favorite books, each book has list of user rating, from all of the users. And also there is a list of UserRatings that contains all of ratings from that user. I dont want neither.
Basically, is there a way to make it so when i do a search for list of books, every book object contains UserRating(One user rating) from a specific User that is logged in?
#Entity
#Table(name = "user_rating")
public class user_rating {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column
private Integer Id;
#Column
private String rating;
#ManyToOne
#JoinColumn(name = "user_id")
private users user;
#ManyToOne
#JoinColumn(name = "book_id")
private books book;
#Entity
#Table(name = "users")
public class users {
#Id
#Column
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column
private String name;
#Column(name = "last_name")
private String lastName;
#Column(name = "email")
private String email;
#Column(name = "date_of_creation")
private java.sql.Date dateOfCreation;
#Column
private String password;
#JsonManagedReference
#ManyToMany
#JoinTable(
name = "favourites",
joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "book_id", referencedColumnName = "id")
)
private Set<books> favourites = new HashSet<>();
#OneToMany(mappedBy ="user")
private List<user_rating> UserRating = new ArrayList<>();
#Entity
#Table(name = "books")
public class books {
#Id
#Column
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column
private String name;
#Column
private String description;
#Column(name = "date_of_creation")
private java.sql.Date date_of_creation;
#Column
private String text_file;
#JsonBackReference
#ManyToMany(mappedBy = "favourites")
private Set<users> users = new HashSet<>();
#JsonManagedReference
#ManyToMany()
#JoinTable(
name = "book_tags",
joinColumns = #JoinColumn(name = "book_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "tag_id", referencedColumnName = "id")
)
private List<tags> tags = new ArrayList<>();
#OneToOne
#PrimaryKeyJoinColumn
private audio_file audioFile;
#OneToMany(mappedBy = "book")
private List<user_rating> UserRatings = new ArrayList<>();
I'm new with Hibernate and Criteria Query.
How can I implement it with Hibernate Criteria Object?
SELECT stateslocalization.StateId, stateslocalization.localization AS name
FROM processstate
Join states ON states.id = processstate.StateId
JOIN stateslocalization ON stateslocalization.StateId = states.id
WHERE processstate.ProcessId = 38 and processstate.StateId = states.id AND stateslocalization.StateId = states.id
Entities:
Process:
#Entity
#Table(name = "processes")
public class Process {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name;
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
#JoinTable(
name = "processstate",
joinColumns = {#JoinColumn(name = "ProcessId")},
inverseJoinColumns = {#JoinColumn(name = "StateId")}
)
private Set<State> states;
//getters and setters.....
}
State:
#Entity
#Table(name = "states")
public class State {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private int id;
private String name;
#ManyToMany(mappedBy = "states", cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
private Set<Process> processes;
#OneToOne(mappedBy = "state")
private StateLocalization stateLocalization;
//getters and setters.....
}
StateLocalization:
#Entity
#Table(name = "stateslocalization")
public class StateLocalization {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "StateId", referencedColumnName = "id")
private State state;
private String localization;
//getters and setters.....
}
I did it with native query but I don't know how I can implement it to Hibernate Criteria, because I don't have entity processstate (it's only table).
I have problems to solve this relationship between User and Roles.
I was able to resolve the relations between User-Organization and Organization-Roles
How can I solve it using notations?
EDIT
I have these classes:
Organization Class
#Entity
#Table(name = "Organizations")
public class Organization implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
private String name;
private String imgLogo;
#ManyToMany
#JoinTable(
name = "OrganizationRoles",
joinColumns = {#JoinColumn(name = "organizationId",
referencedColumnName = "id", updatable = false)},
inverseJoinColumns = {#JoinColumn(name = "roleId",
referencedColumnName = "id", updatable = false)}
)
private List<Role> roles;
....
}
User Class
#Entity
#Table(name = "Users")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
private String name;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "organizationId", nullable = false)
private Organization organization;
????????
private List<Role> roles;
...
}
Thank you!
Tables
I have a database with several entities, in particular Book and User. Between them there exists a ManyToMany relationship like this:
Book:
#Entity
#Table(name = "Books")
public class Book implements Serializable
{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
#Column(name = "bookId", nullable = false, unique = true)
private Long id;
#Column(name = "title", nullable = false)
private String title;
#Column(name = "price", nullable = false)
private int price;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "User_Book",
joinColumns = #JoinColumn(name = "bookId"),
inverseJoinColumns = #JoinColumn(name = "userId"))
private Set<UserAccount> users;
User:
#Entity
#Table(name = "UserAccounts")
public class UserAccount implements Serializable
{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
#Column(name = "userId", nullable = false, unique = true)
private Long id;
#Column(name = "username", nullable = false, unique = true)
private String username;
#Column(name = "password", nullable = false)
private String password;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "User_Book",
joinColumns = #JoinColumn(name = "userId"),
inverseJoinColumns = #JoinColumn(name = "bookId"))
Set<Book> purchasedBooks;
Everything works fine, the table User_Book is indeed created in the database. The problem seems to be related to the access of this Table.
For example,
Query query = entityManager.createQuery("SELECT u FROM User_Book u");
keeps telling me the following:
The abstract schema type 'User_Book' is unknown
So, shall I create from scratch the User_Book entity? Will it get automtically populated like now, that is, whenever a user buys a book, will this purchase be recorded in the table?
User_Book is not an entity. Therefore you cannot use createQuery, BUT you can use createNativeQuery to execute a SQL query:
Query query = entityManager.createNativeQuery("SELECT * FROM User_Book");
The result will be List<Object[]>
I am trying to add Staff object which has staff information, roles and subjects. The code below saves only Staff data not its associated collections data.
I have tried to debug it but didn't understand the issue. The staff object has roles and subjects before saving into database but they are not getting saved in the DB. Surprisingly, the similar code is working while saving Course table data; however, Course does also have collection of Subject class.
It seems to me that Subjects have Course object which may be creating problem, I am not sure why. Please advise how to fix it.
The complete project is available on GitHub(https://github.com/ravinain/practice/tree/master/Java/Spring/SchoolProject)
Staff.java
#Entity
#Table
public class Staff extends Person {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private double salary;
#OneToMany(mappedBy = "staff", fetch=FetchType.EAGER)
#Cascade({ CascadeType.ALL})
private Set<Role> roles = new HashSet<Role>();
#ManyToMany(mappedBy = "staffs", fetch=FetchType.EAGER)
#Cascade({CascadeType.ALL})
private Set<Subject> subjects = new HashSet<Subject>();
Role.java
#Entity
#Table
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#NotNull
private int id;
private String name;
#ManyToOne
#JoinTable(name = "role_staff", joinColumns = #JoinColumn(name = "role_id", referencedColumnName = "id"), inverseJoinColumns = #JoinColumn(name = "staff_id", referencedColumnName = "id"))
#JsonIgnore
private Staff staff;
Subject.java
#Entity
#Table
public class Subject implements Comparable<Subject>{
#Id
#Column
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String description;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "subject_staff", joinColumns = #JoinColumn(name = "subject_id", referencedColumnName = "id"), inverseJoinColumns = #JoinColumn(name = "staff_id", referencedColumnName = "id"))
#JsonIgnore
private Set<Staff> staffs = new HashSet<Staff>();
#ManyToMany(mappedBy = "subjects", fetch = FetchType.EAGER)
#Cascade({ CascadeType.DELETE, CascadeType.SAVE_UPDATE })
#JsonIgnore
private Set<Course> courses = new HashSet<Course>();
#ManyToMany(mappedBy = "subjects", fetch = FetchType.EAGER)
#Cascade({ CascadeType.DELETE, CascadeType.SAVE_UPDATE })
#JsonIgnore
private Set<Student> students = new HashSet<Student>();
DAO Code:
public Staff addStaff(Staff staff) {
Session session = sessionFactory.getCurrentSession();
session.save(staff);
return staff;
}
POST Request:
{"name":"New Test","age":22,"gender":"Female","salary":12000,"roles":[{"id":3,"name":"Teacher"}],"subjects":[{"id":1,"description":"Math"},{"id":2,"description":"English"}]}