Issue
I am trying to @JoinColumn two entities, named Member and Team. One Team can have multiple Members, and They can refer to each other.
package hellojpa;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
public class Member {
@Id
@GeneratedValue
@Column(name= "MEMBER_ID")
private Long id;
private String name;
private int age;
@OneToMany(mappedBy = "member")
private List<Order> orders = new ArrayList<Order>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TEAM_ID")
private Team team;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void setTeam(Team team) {
this.team = team;
team.getMembers().add(this);
}
}
package hellojpa;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
public class Team {
@Id
@GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
@OneToMany(mappedBy = "team",fetch = FetchType.LAZY)
private List<Member> members = new ArrayList<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public List<Member> getMembers() {
return members;
}
public void setName(String name) {
this.name = name;
}
}
When I look up a Member who belongs to a particular team by invoking getMembers()
public class hellojpa {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
try {
Member member =new Member();
member.setName("member1");
member.setAge(20);
Team team = new Team();
team.setName("team a");
em.persist(team);
member.setTeam(team);
em.persist(member);
Member member2 = new Member();
member2.setName("member222");
member2.setTeam(team);
em.persist(member2);
em.flush();
em.clear();
List<Member> memberList = em.find(Team.class, team.getId()).getMembers();
for (Member member1 : memberList) {
System.out.println(member1.getName());
}
} catch (Exception e) {
transaction.rollback();
} finally {
em.close();
}
emf.close();
}
}
I expected that Hibernate creates following query:
select
member0_.MEMBER_ID
members0_.TEAM_ID
members0_.age
members0_.name
from
Member members0_
where
members0_.TEAM_ID=?
but actually,
select
members0_.TEAM_ID as team_id4_0_0_,
members0_.MEMBER_ID as member_i1_0_0_,
members0_.MEMBER_ID as member_i1_0_1_,
members0_.age as age2_0_1_,
members0_.name as name3_0_1_,
members0_.TEAM_ID as team_id4_0_1_
from
Member members0_
where
members0_.TEAM_ID=?
There are duplicated columns with TEAM_ID and MEMBER_ID in select paragraph. Is there any way to solve this problem? and I wonder why this is happening
Solution
I guess this is due to the fact that Hibernate fetches the foreign key columns explicitly, regardless if they are part of the target entity table or not. This is probably to simplify the logic, since the FK columns could be part of a join table as well. In Hibernate 6 this will be fixed. Anyway, you shouldn't be too bothered by this duplication as this usually only happens for foreign key columns anyway. If the datatypes for these columns are very wide, you will have other problems already (join performance) and the result performance will be the least of your worries.
Answered By - Christian Beikov