Cannot create Entity in DB without exception - mysql

I run my app, and everything work nicely. My entities are created in the DB, but in spite of this, I have next exception.
Error executing DDL "alter table user add constraint UK_ob8kqyqqgmefl0aco34akdtpe unique (email)" via JDBC Statement
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table user add constraint UK_ob8kqyqqgmefl0aco34akdtpe unique (email)" via JDBC Statement
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final]
at org.hibernate.tool.schema.internal.SchemaCreatorImpl.applySqlString(SchemaCreatorImpl.java:502) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final]
at org.hibernate.tool.schema.internal.SchemaCreatorImpl.applySqlStrings(SchemaCreatorImpl.java:486) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final]
at org.hibernate.tool.schema.internal.SchemaCreatorImpl.createFromMetadata(SchemaCreatorImpl.java:402) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final]
at org.hibernate.tool.schema.internal.SchemaCreatorImpl.performCreation(SchemaCreatorImpl.java:176) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final]
at org.hibernate.tool.schema.internal.SchemaCreatorImpl.doCreation(SchemaCreatorImpl.java:144) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final]
at org.hibernate.tool.schema.internal.SchemaCreatorImpl.doCreation(SchemaCreatorImpl.java:128) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final]
... 35 common frames omitted
My properties table is create
My Entities
Entity
#Table (name = "User")
public class User {
#Id
#GeneratedValue (strategy = GenerationType.IDENTITY)
#Column (name = "user_id", nullable = false)
private Long userId;
#Basic
#Column (name = "email", nullable = false, length = 4096, unique = true)
private String userEmail;
#Basic
#Column (name = "password", nullable = false, length = 4096)
private String userPassword;
#ManyToMany (fetch = FetchType.EAGER)
#NotFound(action = NotFoundAction.IGNORE)
#JoinTable (name = "user_role",
joinColumns = {#JoinColumn (name = "user_id")},
inverseJoinColumns = {#JoinColumn (name = "role_id")})
private Set <Role> roles = new HashSet<>();
#OneToOne (mappedBy = "user")
private Student student;
#OneToOne (mappedBy = "user")
private Instructor instructor;
public User () {}
If you know please say what I need to do, thanks!

Related

Spring + Hibernate don't create a Query

Can not create table in MYSQL, because something wrong with my Query or parameters in Entity, i don't understand. Everything i checked, everything i saw, but dont work. Please help
My Interface
public interface CourseDao extends JpaRepository <Course, Long> {
List <Course> findCourseBycourseName (String keyword);
#Query (value = "select * from courses as c where c.course_id in (select e.course_id from enrolled_in as e where e.student_id = :studentId)")
List <Course> getCourseBylistStudent (#Param ("studentId") Long studentId);
}
Entity Course
#Entity
#Table (name = "courses")
public class Course {
#Id
#GeneratedValue (strategy = GenerationType.IDENTITY)
#Column (name = "course_id", nullable=false)
private Long courseId;
#Basic
#Column (name = "name", nullable=false, length = 45)
private String courseName;
#Basic
#Column (name = "duration", nullable=false, length = 45)
private String courseDuration;
#Basic
#Column (name = "description", nullable=false, length = 45)
private String courseDescription;
#ManyToOne (fetch = FetchType.LAZY)
#JoinColumn (name = "instructor_id", referencedColumnName = "instructor_id", nullable = false)
private Instructor instructor;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable (name = "enrolled_in",
joinColumns = {#JoinColumn (name = "course_id")},
inverseJoinColumns = {#JoinColumn (name = "student_id")})
private Set<Student> listStudent = new HashSet<>();
Student Entity
#Entity
#Table (name ="Students")
public class Student {
#Id
#GeneratedValue (strategy = GenerationType.IDENTITY)
#Column (name = "student_id", nullable = false)
private Long studentId;
#Basic
#Column (name = "first_name", nullable = false, length = 45)
private String firstName;
#Basic
#Column (name = "last_name", nullable = false, length = 45)
private String lastName;
#Basic
#Column (name = "level", nullable = false, length = 45)
private String studentLevel;
#ManyToMany (mappedBy = "listStudent", fetch = FetchType.LAZY)
private Set <Course> courses = new HashSet<>();
#OneToOne (cascade = CascadeType.REMOVE)
#JoinColumn (name = "user_id", referencedColumnName = "user_id", nullable = false)
private User user;
Log
Error creating bean with name 'courseDao' defined in spring.dao.CourseDao defined in #EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Could not create query for public abstract java.util.List spring.dao.CourseDao.getCourseBylistStudent(java.lang.Long); Reason: Validation failed for query for method public abstract java.util.List spring.dao.CourseDao.getCourseBylistStudent(java.lang.Long)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1751) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:915) ~[spring-context-6.0.2.jar:6.0.2]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584) ~[spring-context-6.0.2.jar:6.0.2]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[spring-boot-3.0.0.jar:3.0.0]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432) ~[spring-boot-3.0.0.jar:3.0.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-3.0.0.jar:3.0.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[spring-boot-3.0.0.jar:3.0.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291) ~[spring-boot-3.0.0.jar:3.0.0]
at spring.CourseSystemApplication.main(CourseSystemApplication.java:12) ~[classes/:na]
Caused by: org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.List spring.dao.CourseDao.getCourseBylistStudent(java.lang.Long); Reason: Validation failed for query for method public abstract java.util.List spring.dao.CourseDao.getCourseBylistStudent(java.lang.Long)
at java.base/java.util.Optional.map(Optional.java:260) ~[na:na]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.<init>(QueryExecutorMethodInterceptor.java:88) ~[spring-data-commons-3.0.0.jar:3.0.0]
at
Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List spring.dao.CourseDao.getCourseBylistStudent(java.lang.Long)
Caused by: org.hibernate.query.SemanticException: A query exception occurred [select * from courses as c where c.course_id in (select e.course_id from enrolled_in as e where e.student_id = :studentId)]
... 48 common frames omitted
In other interface everything work, but with CourseDao have some problem, if you know, please help me!
Use nativeQuery=true when using MySQL queries in spring data jpa.
#Query(nativeQuery = true, value = "your query")

Spring delete row of join table

I have two entities User:
public class User {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long userID;
#Column(name = "userHashedPassword")
private String password;
#Column(name = "userName")
private String userName;
#Column(name = "userEmail")
private String email;
#Transient
private List<String> groups = new LinkedList<>();
#ManyToMany
#JoinTable(name = "UserRoles",
joinColumns = #JoinColumn(
name = "userID"),
inverseJoinColumns = #JoinColumn(
name = "roleID"))
private Set<Role> roles = new HashSet<>();
#OneToMany(mappedBy = "user")
private Set<Rating> ratings;
protected User(){}
public User(String userHashedPassword, String userName, String email, Set<Role> roles){
this.password = userHashedPassword;
this.userName = userName;
this.email = email;
this.roles = roles;
}
//getters and setters
}
And Group:
#Table(name="FocusGroups")
#Entity
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "groupID")
public class Group {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long groupID;
private String groupName;
#ManyToMany
#JoinTable(name = "GroupMembers",
joinColumns = #JoinColumn(
name = "groupID"),
inverseJoinColumns = #JoinColumn(
name = "userID"))
private Set<User> groupMembers = new HashSet<>();
#ManyToOne(fetch = FetchType.EAGER, optional = true)
#JoinColumn(name="frameworkID", nullable = true)
private Framework framework;
public Group(){}
public Group(String groupName, Set<User> groupMembers, Framework framework) {
this.groupName = groupName;
this.groupMembers = groupMembers;
this.framework = framework;
}
//getters setters
}
When I delete a User, I want to remove them from group members, however it fails due to foreign key constraint: java.sql.SQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (capripol.groupmembers, CONSTRAINT FK98tbu0sjfsn1m5p340dn0v8wo FOREIGN KEY (userID) REFERENCES users (userID))
How do I work around this?
Well, I will try to answer: First of all, it is rather strange you refer on Groups in user
entity like that:
#Transient
private List<String> groups = new LinkedList<>();
It this case, you will not have a column group in user table in database, hence you have to first perform removal from group_members for an all groups:
delete from group_members where userid = <user_id_you_want_to_remove>;
And only after your JoinTable table does not contain any refers to user with <user_id_you_want_to_remove>, than you can execute
delete from users where userid = 1;
Note: there is no matter you do it by spring data (e.g. deleteById(Long id) and using #Query annotation specify the query above in SQL or HQL, up to you) - this will work. But I highly recommend you to reconsider you database structure - it is not cute to store only one entity.

Hibernate Annotations : Many-to-Many relationship using Join table having common attribute in PK

Is it possible to define a many to many relationship between two tables using a join table which has composite key, having a common attribute between the two tables?
Let's say, we have a table structure like below and am trying to define association between kit and business_product using kit_business_product table. Here are the table definitions (simplified for this question).
Table 1 : kit
PK1 : kit_id, business_id
Table 2 (Join Table) : kit_business_product
PK2 : kit_id, business_id, manufacturer_id, product_id, name
Table 3 : business_product
PK3 : business_id, manufacturer_id, product_id, name
Here are the java classes for these tables (simplified for this question).
Kit.java
#Entity
#Table (name= "kit")
public class Kit
{
#EmbeddedId
private KitId id;
#ManyToMany
#JoinTable(name = "kit_business_product",
joinColumns = {#JoinColumn(name = "kit_id", referencedColumnName = "kit_id", nullable = false, insertable = false, updatable = false),
#JoinColumn(name = "business_id", referencedColumnName = "business_id", nullable = false, insertable = false, updatable = false)},
inverseJoinColumns = {
#JoinColumn(name = "business_id", referencedColumnName = "business_id", nullable = false),
#JoinColumn(name = "manufacturer_id", referencedColumnName = "manufacturer_id", nullable = false),
#JoinColumn(name = "product_id", referencedColumnName = "product_id", nullable = false),
#JoinColumn(name = "name", referencedColumnName = "name", nullable = false)
})
private Set<BusinessProduct> businessProducts = new HashSet<BusinessProduct>();
}
KitId.java
#Embeddable
public class KitId
{
#Column (name = "kit_id")
private String kitId;
#Column (name = "business_id")
private long businessId;
}
BusinessProduct.java
#Entity
#Table(name = "business_product")
public class BusinessProduct
{
#EmbeddedId
private BusinessProductId id;
}
BusinessProductId.java
#Embeddable
public class BusinessProductId
{
#Column(name = "business_id")
private long businessId;
#Column(name = "manufacturer_id")
private long manufacturerId;
#Column(name = "product_id")
private String productId;
#Column(name = "name")
private String name;
}
With this code, I get the below given error.
[RMI TCP Connection(3)-127.0.0.1] 2017-03-17 14:17:54,767 ERROR com.common.DatabaseSession [] Repeated column in mapping for collection: com.hibernate.Kit.businessProducts column: business_id
org.hibernate.MappingException: Repeated column in mapping for collection: com.hibernate.Kit.businessProducts column: business_id
at org.hibernate.mapping.Collection.checkColumnDuplication(Collection.java:341) ~[hibernate3.jar:3.6.10.Final]
at org.hibernate.mapping.Collection.checkColumnDuplication(Collection.java:364) ~[hibernate3.jar:3.6.10.Final]
What would be the correct annotation for such a scenario? Any insight would be greatly appreciated. Thanks!

adminId not saving in user table in a one to one relationship springboot

I have mapped a one to many relationship between a user and an admin as shown in the user class
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "userId")
private Long id;
#Column(nullable = false)
private String name;
#Column(unique = true, nullable = false)
private String email;
#Column(nullable = false)
private long timestamp;
#OneToOne
#JoinColumn(name = "adminId")
Admin admin;
Now I am trying to save a user by inserting a value of 1 to the adminId field in the users table using SessionFactory of hibernate as shown
public void save(User user) {
//User userAdmin = new User();
long id = 1 ;
user.setId(id);
getSession().save(user);
}
EDITTED
Considering getters and setters, these are the fields in the admin table
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "adminId")
private Long id;
#Column(nullable = false)
private String name;
#Column(nullable = true)
private String department;
My challenge is that when I save, nothing gets inserted (that is value of 1) on the adminId field referencing the admin foreign key in the users table.
Kindly assist!
You'll have to get the Admin entity with id 1 first and then set it on the new User:
#Transactional
public void save(User user) {
Admin admin = getSession.createQuery("from Admin a where a.id = ?)
.setParameter(0, 1);
user.setAdmin(admin);
getSession().save(user);
}

Data lost when trying to edit record

I'm currently having this issue: I have 3 tables: users, roles and users_roles as in the picture below:
whenever I edit any of the record in users table, the record of that user in the users_roles table will be lost.
For example, I changed the username of the user which holds the userId = 2, then in the users_roles table, the row of userId = 2 will be lost.
Anybody has any ideas of this problem? I'm using Spring with Hibernate
*UPDATE
In my Role.java
#ManyToMany(fetch = FetchType.EAGER, mappedBy = "roles")
private List<User> users;
In my User.java
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(name = "users_roles", joinColumns = #JoinColumn(name = "userId", nullable = false) , inverseJoinColumns = #JoinColumn(name = "roleId", nullable = false) )
private List<Role> roles;
And in my UsersRoles.java
#Id
#Column(name="userId")
private int userId;
#Id
#Column(name="roleId")
private int roleId;
This is the DAO implementation method I used for Edit
#Override
public void edit(User user) {
session.getCurrentSession().saveOrUpdate(user);
}
P/S: this not only happens when I edit with my web-app, but also happens when I edit directly in MySQL environment. I don't know...