복붙노트

[SPRING] Hibernate (4.1.2) 및 Spring (3.1.2) - ManyToMany 관계는 JoinTable에 레코드를 저장하지 않습니다.

SPRING

Hibernate (4.1.2) 및 Spring (3.1.2) - ManyToMany 관계는 JoinTable에 레코드를 저장하지 않습니다.

문제가있어이 문제를 극복하기 위해 도움이 필요합니다. 바라기를,이 밟는 것은 유사한 문제점을위한 참고가 될지도 모른다 ...

내 최소화 된 비즈니스 모델에는 사용자와 타이틀이 있습니다. 제목은 먼저 만들어 져야하며 많은 사용자에게 할당 될 수 있으며 사용자는 동일한 제목을 공유 할 수 있습니다. 따라서 @ManyToMany 관계가있는 User 및 Title이라는 두 개의 엔티티를 작성하고 Title이이 관계를 소유해야한다고 결정했습니다. 또한이 예제를 실행하는 UnitTest가 있습니다.

사용자 개체

public class User {

    Long id;
    String name;
    Set<Title> titles = new HashSet<Title>();

    @Id
    @GeneratedValue
    @Column(name = "id")    
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "name")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    /*============ Approach1 ============*/
//  @ManyToMany(mappedBy = "users")
    /*============ Approach2 ============*/
//  @ManyToMany
    /*============ Approach3 ============*/
    @ManyToMany
    @JoinTable( name = "tb_title_user",
                joinColumns = @JoinColumn(name = "user_id"),
                inverseJoinColumns = @JoinColumn(name = "title_id"))
    public Set<Title> getTitles() {
        return titles;
    }
    public void setTitles(Set<Title> titles) {
        this.titles = titles;
    }

}

타이틀 개체

public class Title {

    Long id;
    String description;
    Set<User> users = new HashSet<User>();


    @Id
    @GeneratedValue
    @Column(name = "id")    
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "description")
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

    /*============ Approach1 & Approach2 & Approach3 ============*/
    @ManyToMany
    @JoinTable( name = "tb_title_user",
                joinColumns = @JoinColumn(name = "title_id"),
                inverseJoinColumns = @JoinColumn(name = "user_id"))
    public Set<User> getUsers() {
        return users;
    }
    public void setUsers(Set<User> users) {
        this.users = users;
    }
}

단위 테스트

public class UserTest {

    @Autowired
    private SessionFactory sessionFactory;


    @Test
    @Rollback(false)
    @Transactional
    public void saveUser(){
        Session session = sessionFactory.getCurrentSession();
        String now = new Date().toString();

        Title title = new Title();
        title.setDescription("TitleDescription: " + now);
        session.save(title);

        User user = new User();
        user.setName("UserName: " + now);
        user.getTitles().add(title);

        session.saveOrUpdate(user);
    }

}

위의 코드를 보면 세 가지 접근 방식을 보게 될 것입니다. 아래는 데이터가 데이터베이스 테이블에 올바르게 저장되어있는 경우입니다.

             Title      User     JoinTable
Approach1    Yes        Yes      No
Approach2    Yes        Yes      Yes
Approach3    Yes        Yes      Yes

각 접근법에 대한 내 생각은 다음과 같습니다.

접근법 1

Hibernate 문서 (http://docs.jboss.org/hibernate/core/4.1/manual/en-US/html/ch07.html#d5e5537)에 따르면 Approach1을 따라야한다. 특히 문서에서 명시 적으로 언급하기 때문에 :

내가 이해했다면 User 엔티티에 @JoinTable을 추가 할 필요는 없습니다.

접근법 2

작동하지만, @JoinTable 정의를 무시하고 tb_user_tb_title이라는 자체 테이블을 작성합니다. 그것은 나에게 생선 냄새가 난다.

접근법 3

그것은 작동하지만 문서는 그것을 사용하지 말합니다. 따라서 엔터프라이즈 제품에서이 접근 방식을 사용하면 후회할 수 있습니다.

해결법

  1. ==============================

    1.유일한 올바른 방법은 첫 번째 방법입니다.

    유일한 올바른 방법은 첫 번째 방법입니다.

    @ManyToMany(mappedBy = "users")
    public Set<Title> getTitles() {
        return titles;
    }
    
    ...
    
    @ManyToMany
    @JoinTable(name = "tb_title_user",
               joinColumns = @JoinColumn(name = "title_id"),
               inverseJoinColumns = @JoinColumn(name = "user_id"))
    public Set<User> getUsers() {
        return users;
    }
    

    반대면은 mappedBy 속성을 사용하여 말합니다. "나는 반대쪽입니다. 대상 엔티티의 사용자 속성을보고이 연관이 어떻게 매핑되는지보십시오."

    당신이 잘못하고있는 것은 테스트에서 역변환 만 수정한다는 것입니다. JPA / Hibernate는 단지 연관이 존재 하는지를 소유자 측이 알 수 있다고 간주한다. 그래서 대신

    user.getTitles().add(title);
    

    너는해야한다.

    title.getUsers().add(user);
    

    객체 그래프가 일관성이 있는지 확인하기 위해 두 가지 모두를 수행하십시오.

    나는이 흙 받이가 유사한 문제에 대한 참고가되기를 바란다. 그러나 나는이 질문에 이미 많은 시간을 대답했기 때문에 의심 스럽다. 문서에 분명히 설명되어 있지만 몇 번이고 계속 반복된다.

  2. from https://stackoverflow.com/questions/15438531/hibernate-4-1-2-and-spring-3-1-2-manytomany-relationship-does-not-store-re by cc-by-sa and MIT license