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")})
Related
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"))
I have the following scenario:
I have an entity called MyOtherEntity that has a type attribute.
MyEntity is associated only with certain MyOtherEntity entities based on the type of MyOtherEntity.
MyEntity class (only for demonstration it's not modelled correctly):
#Data
#Entity
#Table(name = "my_table")
public class MyEntity {
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(
name = "my_entity_my_other_entity_type1",
joinColumns = {#JoinColumn(name = "my_entity_id")},
inverseJoinColumns = {#JoinColumn(name = "my_other_entity_id")}
)
private List<MyOtherEntity> myOtherEntityType1;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(
name = "my_entity_my_other_entity_type2",
joinColumns = {#JoinColumn(name = "my_entity_id")},
inverseJoinColumns = {#JoinColumn(name = "my_other_entity_id")}
)
private List<MyOtherEntity> myOtherEntityType2;
// more fields
}
MyOtherEntity class:
#Data
#Entity
#Table(name = "my_other_entity")
public class MyOtherEntity {
private String type;
// more fields
}
A more detailed example:
Let's say there are only 3 types of MyOtherEntity type1, type2, and type3. My goal is to only associate MyEntity with MyOtherEntity entities of type1 and type2.
Is this functionality possible to achieve using Hibernate?
You can use #Where annotation.
#Where(clause = "type = 'tyep1'")
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(
name = "my_entity_my_other_entity_type1",
joinColumns = {#JoinColumn(name = "my_entity_id")},
inverseJoinColumns = {#JoinColumn(name = "my_other_entity_id")}
)
private List<MyOtherEntity> myOtherEntityType1;
#Where(clause = "type = 'tyep2'")
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(
name = "my_entity_my_other_entity_type2",
joinColumns = {#JoinColumn(name = "my_entity_id")},
inverseJoinColumns = {#JoinColumn(name = "my_other_entity_id")}
)
private List<MyOtherEntity> myOtherEntityType2;
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>();
}
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<>();
I found here a good article about designing the many-to-many schema with JPA.
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "student_subject", joinColumns = #JoinColumn(name = "student_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "subject_id", referencedColumnName = "id"))
private Set<Subject> subjects;
My question is, can I map a start schema, for example on JoinColumn I want to add multiple tables. It is possible?