복붙노트

[SPRING] 여분의 many-to-many 테이블을 생성하는 Hibernate

SPRING

여분의 many-to-many 테이블을 생성하는 Hibernate

스프링 부트 애플리케이션을 개발하는 동안 데이터베이스를 삭제하고 hibernate가 hibernate.hbm2ddl.auto = update를 사용하여 다시 생성해야했습니다. 그 후 나는 내가 원했던대로 모든 것을했는지 확인하기를 원했고, 그래서 나는 전체 데이터베이스를 리버스 엔지니어하기 위해 MySQL Workbench를 불렀다. 내가 그렇게했을 때, 나는 어떤 이유로 스키마에 두 배의 테이블이 있다는 것을 알았습니다. 나는 테이블에 많은 엔티티 관계를 가지고 있지만 모두 일대 다이지만 Hibernate가 다 대다 (many-to-many) 조인 테이블을 생성 한 거의 모든 일 - 대 - 다 관계에 대한 어떤 이유로 든. 이것은 같은 웹 애플리케이션으로 이전에 발생하지 않았기 때문에 나에게 놀랄만 한 일이었습니다.

SO를 통한 나의 검색은 관련성이없는 것으로 보이는이 질문으로 안내 할뿐입니다.

이제 샘플을 제공 하겠지만 코드가 많아 짧게 유지하려고하므로 단 하나의 예제 만 잘라냅니다. 더 많이 볼 필요가 있다면 답안에 이것을 명시하십시오.

예를 들어, 저는이 엔티티를 가지고 있습니다 :

@SuppressWarnings("serial")
@Entity
@Indexed
@Table(name = "SKILL")
public class Skill extends AbstractDomainObject {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private long id;

//Some properties

@ManyToOne(fetch = FetchType.EAGER, targetEntity = Skill.class)
@JoinColumn(name = "PARENT", nullable = true)
@Cascade({CascadeType.DETACH}) 
//Cascade annotations are from Hibernate, all else except for 
//"Indexed" are from javax.persistence
private Skill parent;

@OneToMany(fetch = FetchType.EAGER, targetEntity = Skill.class)
@Cascade({CascadeType.DETACH})
private Set<Skill> children;

//Getters, setters, etc
}

이 엔터티가 자신을 참조하는 것을 볼 수 있습니다. 기술은 여기에 나무입니다. 그래서 Hibernate는 이것을 다음과 같이 해석한다.

skill_skill 이미지

사실, skill_skill 테이블은 사용되지 않습니다. 이 스킬이 여전히이 테이블없이 참조되는 것을 볼 수 있습니다. 이 테이블에 새 데이터를 삽입하면 skill_skill에 새 항목이 나타나지 않습니다. 이러한 두 엔티티가 어떤 이유로 든 추가 테이블을 확보하지 못하더라도 :

역할 및 사용자 이미지

이 두 객체는 ​​여기에 한쪽 관계가 있습니다.

@SuppressWarnings("serial")
@Entity
@Table(name = "ROLE")
public class Role implements DomainObject {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private long id;

@Column(name = "ROLENAME", nullable = false, length = 50)
private String rolename;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "OWNER", nullable = false)
private User owner;
}

내가 생각할 수있는 몇 가지 원인 :

해결법

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

    1.여기 양측이 소유자 인 양방향 협회가 있습니다. 기본적으로 두 개의 독립적 인 협회로 연결됩니다. 일대 다 연관에서 소유자는 일반적으로 many-to-side입니다 (mappedBy 특성 참고).

    여기 양측이 소유자 인 양방향 협회가 있습니다. 기본적으로 두 개의 독립적 인 협회로 연결됩니다. 일대 다 연관에서 소유자는 일반적으로 many-to-side입니다 (mappedBy 특성 참고).

    OneToMany(fetch = FetchType.EAGER, targetEntity = Skill.class, mappedBy = "parent")
    @Cascade({CascadeType.DETACH})
    private Set<Skill> children;
    

    이 방식으로 Hibernate는 관계를 유지할 때 일대일을 무시할 것이다. @JoinColumn없이 @OneToMany 연관에 대한 기본 설정 인 join 테이블을 생성하지 않을 것이다.

  2. ==============================

    2.@JoinColumn없이 @OneToMany를 사용하면 Hibernate는 조인 테이블을 생성한다.

    @JoinColumn없이 @OneToMany를 사용하면 Hibernate는 조인 테이블을 생성한다.

    @OneToMany(fetch = FetchType.EAGER, targetEntity = Skill.class)
    @Cascade({CascadeType.DETACH})
    private Set<Skill> children;
    

    그것을

    @OneToMany(fetch = FetchType.EAGER)
    @Cascade({CascadeType.DETACH})
    @JoinColumn
    private Set<Skill> children;
    

    불필요한 매핑 속성을 사용하지 마십시오. - targetEntity = Skill.class

    그리고이 협회를 사용할 필요가 있는지 확신하지 못합니다.

    private Skill parent; 
    

    사용자가 여러 역할을 가질 수 있고 각 역할이 여러 사용자에게 속할 수 있으므로 @OneToMany 연결을 사용하여 사용자와 역할을 연결하는 것은 올바르지 않습니다. 그러한 연관에는 @ManyToMany를 사용하십시오.

    사용자와 역할 간의 연결 예

  3. from https://stackoverflow.com/questions/35989185/hibernate-creating-redundant-many-to-many-tables by cc-by-sa and MIT license