I have two tables joining with a mapping table. I am getting a null constraint issue though. Below is the error message and the two mappings. Since both are manyTomany my assumption is that the many could be none, how can I make it so either product_id or category_id can be null?
Error Message
Caused by: org.h2.jdbc.JdbcBatchUpdateException: NULL not allowed for column "PRODUCT_OPTION_ID"; SQL statement:
insert into ImageMapping (product_id, image_id) values (?, ?) [23502-168]
Categories
#JoinTable(
name = "ImageMapping",
joinColumns = #JoinColumn(name = "category_id"),
inverseJoinColumns = #JoinColumn(name = "image_id")
)
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
private Set<Image> categoryImageId;
Products
#JoinTable(
name="ImageMapping",
joinColumns = #JoinColumn(name = "product_id"),
inverseJoinColumns = #JoinColumn(name = "image_id")
)
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
private Set<Image> productImageGroup;
Product Options
#JoinTable(
name="ImageMapping",
joinColumns = #JoinColumn(name = "product_option_id"),
inverseJoinColumns = #JoinColumn(name = "image_id")
)
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Set<Image> productOptionImageGroup;
You should have a separate join table for each of your associations instead of trying to use the same one for all.
Related
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!
I have an entity called User with two many-to-many relationships: User -mtm - Role and User -mtm - Course
public class User {
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "users_roles",
joinColumns = {#JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = {#JoinColumn(name = "role_id", referencedColumnName = "id")})
private List<Role> userRoles;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "users_courses",
joinColumns = {#JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = {#JoinColumn(name = "course_id", referencedColumnName = "id")})
private List<Course> orderedCourses;
}
In Course entity:
public class Course {
#ManyToMany(mappedBy = "orderedCourses")
private List<User> participants;
}
It looks similar in the Role entity.
When user with e.g. two roles assigned enrolls himself to some course (means that course is added to his orderedCourses list), he gets this course twice.
So the user with two roles gets registered for the same course twice, user with 3 roles gets it three times etc.
It is noticeable in the junction table in the database. (one user has the same course few times which is unacceptable).
Looks like one ManyToMany relationship has an impact on another. But I don't know what is wrong.
Everything is persisted to MySQL database by Hibernate (via Spring Data JPA)
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...
I have a many-to-many association between Photo and Auteur entities, and 3 tables - AUTEUR, PHOTO_AUTEUR and PHOTO.
My Auteur mapping class:
#Entity
#Table(name = "AUTEUR")
public class Auteur implements Serializable {
#Id
#GeneratedValue
#Column(name = "auteur_id")
private int auteur_id;
#Column(name = "nom")
private String nom;
#Column(name = "prenom")
private String prenom;
#ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL},
targetEntity = Photo.class)
#JoinTable(name = "PHOTO_AUTEUR",
joinColumns = {
#JoinColumn(name = "AUTEUR_ID")},
inverseJoinColumns = {
#JoinColumn(name = "PHOTO_ID")})
private Set<Photo> photos = new HashSet<Photo>();
...
}
and a Photo class:
#Entity
#Table(name = "PHOTO")
public class Photo extends News {
#Id
#GeneratedValue
#Column(name = "photo_id")
private int id;
#Column(name = "format")
private String format;
#Column(name = "largeur")
private int largeur;
#Column(name = "hauteur")
private int hauteur;
#Column(name = "siColoree")
private boolean siColoree;
#ManyToMany(mappedBy = "photos", fetch = FetchType.EAGER, cascade = CascadeType.ALL, targetEntity = Auteur.class)
private Set<Auteur> photo_auteurs = new HashSet<>();
#Lob
#Column(name = "image", length = 1000000)
private byte[] image;
...}
and when I try to update or delete Photo entry i get ConstraintViolationException, even if I manually have set cascade deleting and updating in mySql.
It works right without cascade restrictions
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
session.delete(photo);
session.getTransaction().commit();
session.close();
with such mapping in Photo:
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(name = "PHOTO_AUTEUR",
joinColumns = #JoinColumn(name = "PHOTO_ID"),
inverseJoinColumns = #JoinColumn(name = "AUTEUR_ID"))
private Set<Auteur> photo_auteurs = new HashSet<>();
and in Auteur:
#ManyToMany(fetch = FetchType.EAGER, targetEntity = Photo.class)
#JoinTable(name = "PHOTO_AUTEUR",
joinColumns = {
#JoinColumn(name = "AUTEUR_ID")},
inverseJoinColumns = {
#JoinColumn(name = "PHOTO_ID")})
private Set<Photo> photos = new HashSet<>();
In my location table i have list of employee DO and Employee table has locationid as a foreign key ,if i try to insert location DO using ORM-insert, locationid is inserted in the location table but it is null in the employee table. please help me with this issue. thanks in advance
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy ="location")
private List<Employee> employees = new ArrayList<Employee>();
#ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "locationid")
private Location location = null;