Hibernate / JPA Why many-to-many join column id is false? - java

to-many tables mapped like this :
Resume.java :
#ManyToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
#JsonIgnore
#JoinTable(
name = "resume_skills",
joinColumns = #JoinColumn(name = "skill_id"),
inverseJoinColumns = #JoinColumn(name = "resume_id"))
private List<Skill> skills = new ArrayList<Skill>();
public void addSkill(Skill skill) {
skills.add(skill);
skill.getResumes().add(this);
}
Skill.java
#ManyToMany(mappedBy="skills")
#JsonIgnore
private List<Resume> resumes;
I do this :
Resume resumeToAdd = new Resume(resume.getGithubAdress(),
resume.getLinkedinAdress(),
resume.getCoverLetter(),
resume.getPicture(),
employee
);
resumeDao.save(resumeToAdd);
Skill skill = skillService.findById(1).getData();
System.out.println(skill);
resumeToAdd.addSkill(skill);
resumeDao.save(resumeToAdd);
But it occurs an error, for example it added a Resume with id 60 and it's trying to add mapping with skill id 60 But it cant because there is no skill in database with id of 60, it should be 1. What did i miss here?

Looks like you mixed up the order of the mapping. It should be this:
#JoinTable(
name = "resume_skills",
joinColumns = #JoinColumn(name = "resume_id"),
inverseJoinColumns = #JoinColumn(name = "skill_id"))

Related

How to map additional column of many-to-many join table to the association map key?

There is an entity call Version and this entity has an inner join many-to-many relationship. The bridge table VER_EQUIVALENTS has columns [VER_ID, EQUIVALENT_VER_ID, CODE] and the CODE column contains the code of the equivalent version.
This is how I implemented this relationship.
public class Version {
private String code;
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinTable(
name = "VER_EQUIVALENTS",
joinColumns = {#JoinColumn(name = "VER_ID")},
inverseJoinColumns = {#JoinColumn(name = "EQUIVALENT_VER_ID")}
)
#MapKey(name = "code")
#org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
private Map<String, Version> equivalentVersions = new HashMap<String, Version>();
}
This is what I got when I try to insert a version contains equivalent versions.
ORA-01400: cannot insert NULL into ("VER_EQUIVALENTS"."CODE")
What can I do to set the CODE value?
If I correctly understand that you need, you should correct your mapping in the following way:
public class Version {
// ...
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinTable(
name = "VER_EQUIVALENTS",
joinColumns = {#JoinColumn(name = "VER_ID")},
inverseJoinColumns = {#JoinColumn(name = "EQUIVALENT_VER_ID")}
)
#MapKeyColumn(name = "CODE")
private Map<String, Version> equivalentVersions = new HashMap<String, Version>();
}

JPA does not create composite tables in a local postgreSQL Database

so until now I have used a remote server and database and JPA has always created those tables:
but now I have to do something in a local PostgreSQL database and JPA creates only the Entities:
I run the same code. The only thing I have changed is the persistance unit in the Entitimanagerfactory.
Do you guys have any idea why this happens?
Also... I am not posting any code since I don't know where the issue might be and I don't want to post my entire program.
Edit:
#ManyToMany(targetEntity = Question.class, cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
#JoinTable(name = "test",
joinColumns = #JoinColumn(name = "gameId", referencedColumnName = "gameId"),
inverseJoinColumns = #JoinColumn(name = "questionId", referencedColumnName = "questionId"),
uniqueConstraints = #UniqueConstraint(columnNames = {"questionId", "gameId"})
)
private List<Question> questions = new ArrayList<>();
#ManyToMany(targetEntity = Game.class, cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
#JoinTable( name = "test",
joinColumns = #JoinColumn(name = "questionId", referencedColumnName = "questionId"),
inverseJoinColumns = #JoinColumn(name = "gameId", referencedColumnName = "gameId"),
uniqueConstraints = #UniqueConstraint(columnNames = {"questionId", "gameId"})
)
private List<Game> game = new ArrayList<>();

Creating OrderColumn for OneToMany list mapping on a join table in Hibernate

I have a productJob table and a quadrat table. Every quadrat can be installed on many productJob and every productJob can have between 1 and 4 quadrats of the same or different kinds! I'm interested to keep the order of quadrat installation on the product jobs. For example first, second, third or forth place! But the following mapping doesn't create the order column on the JoinTable telai_quadrati. What is the problem of my mapping? The orderColumn isn't created in anyway!
#Entity
#Table(name = "telai")
public class ProductJob implements IProductJob, IProductJobProcessing{
#Embedded private QuadratGroup quadrateGroup = new QuadratGroup();
}
#Embeddable
public class QuadratGroup implements Serializable{
#OneToMany(targetEntity = Quadrat.class, cascade = CascadeType.ALL)
#JoinTable(
name = "telai_quadrati",
joinColumns = {#JoinColumn(name = "dbId", table = "telai")},
inverseJoinColumns = {#JoinColumn(name = "id", table = "quadrati")})
//#OrderColumn(name = "order")
#IndexColumn(name = "order")
public List<Quadrat> getQuadratList(){ //return an ordered list of the quadrats with at most 4 elements}
And it is clear that for the quadrats there exists no order so I use set!
#Entity
#Table(name = "quadrati")
public class Quadrat implements IQuadrat, Cloneable, Serializable{
#ManyToMany
#JoinTable(
name = "telai_quadrati",
joinColumns = #JoinColumn(name = "id", table = "quadrati"),
inverseJoinColumns = #JoinColumn(name = "dbId", table = "telai"))
private Set<ProductJob> productJobs;
It works if I use property access inspite of method access! Like this:
#OneToMany(targetEntity = Quadrat.class, cascade = CascadeType.ALL)
//#MapKeyJoinColumn(name="indice" , table = "telai_quadrati")
#JoinTable(
name = "telai_quadrati",
joinColumns = {#JoinColumn(name = "telaio_id", table = "telai")},
inverseJoinColumns = {#JoinColumn(name = "quadrato_id", table = "quadrati")})
#OrderColumn(name = "indice")
private List<Quadrat> quadratList;
But I wonder why it doesn't work with method access that forces me a heavy refactor in my project! :(

many-to-many where clause

Given 3 tables:
student (id)
student_to_class (student_id, class_id)
class (id)
I'd like to apply a where clause on the student_to_class where student_id = :studentId. I've found many examples that apply where clause on "class" table or "student" table, but not the many-to-many table.
The student table has a #ManyToMany
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(
name = "student_to_class",
joinColumns = { #JoinColumn(name = "student_id", nullable = false) },
inverseJoinColumns = { #JoinColumn(name = "class_id", nullable = false) }
)
private Set<ClassEntity> classes;
The class table has a #ManyToMany
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(
name = "student_to_class",
joinColumns = { #JoinColumn(name = "class_id", nullable = false) },
inverseJoinColumns = { #JoinColumn(name = "student_id", nullable = false) }
)
private Set<StudentEntity> students;
Here is the query I'm trying to translate into Criteria:
select * from student, student_to_class where student_to_class.student_id = 1 and student.id = student_to_class.class_id
I'm trying to figure out how to reference the many-to-many table since I don't have an actual class representing this table.
Criteria c = sessionFactory.getCurrentSession().createCriteria(ClassEntity.class);
c.createAlias("student_to_class", "entities"); // how to reference the student_to_class ?
c.add(Restrictions.eq("entities.user_id", studentEntity.getId()));
But I get an error, which makes sense to me, but I haven't had much luck fixing it:
could not resolve property: student_to_class
Since the studentid in the Student table will be the same as the studentid in the student_to_class table there is no need to filter by the join table. Simply run the where clause against student.student_id

Hibernate ManyToMany mapping

I have ManyToMany mapping like this:
#XmlTransient
#ManyToMany(cascade = {CascadeType.ALL})
#JoinTable(name = "users_clients",
joinColumns = {#JoinColumn(name = "user_id")},
inverseJoinColumns = #JoinColumn(name = "client_id"))
public List<Client> getClients() {
return clients;
}
And other side:
#ManyToMany(mappedBy = "clients")
private List<User> users = new ArrayList<User>();
So as you can see I have JoinColumn name = user_id and client_id but hibernate mapps this columns with names userS_id and clientS_id as their tables names. Why that happening? Any suggestions?
Try specifying the column name in your #JoinColumn annotation. Also you were missing braces around the inverseJoinColumns
#JoinTable(name = "users_clients",
joinColumns = {
#JoinColumn(name = "user_id", referencedColumnName="user_id")},
inverseJoinColumns = {
#JoinColumn(name = "client_id", referencedColumnName="client_id")})

Categories