문제

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Problem {
    @ManyToOne
    private Person person;
}

@Entity
@DiscriminatorValue("UP")
public class UglyProblem extends Problem {}

@Entity
public class Person {
    @OneToMany(mappedBy="person")
    private List< UglyProblem > problems;
}

내가 하려는 일이 무엇인지는 꽤 분명하다고 생각합니다.@ManyToOne 사람이 UglyProblem 클래스에 의해 상속될 것으로 예상합니다.그러나 다음과 같은 예외가 있습니다."UglyProblem 클래스(mappedBy="person")에는 해당 속성이 없습니다."

내가 찾은 건 이것.나는 이에 대한 이유를 설명하는 Emmanuel Bernard의 게시물을 찾을 수 없었습니다.


불행하게도 Hibernate 문서에 따르면 "@MappedSuperclass로 매핑되지 않은 슈퍼클래스의 속성은 무시됩니다."

글쎄요, 제 생각에는 이 두 클래스가 있다면 다음과 같습니다.

public class A {
    private int foo;
}

@Entity
public class B extens A {
}

그런 다음 필드 foo 클래스 B에는 매핑되지 않습니다.말이 되네요.하지만 다음과 같은 것이 있다면:

@Entity
public class Problem {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String name;

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}
}

@Entity
public class UglyProblem extends Problem {

private int levelOfUgliness;

public int getLevelOfUgliness() {
    return levelOfUgliness;
}

public void setLevelOfUgliness(int levelOfUgliness) {
    this.levelOfUgliness = levelOfUgliness;
}
}

UglyProblem 클래스에 파일이 있을 것으로 예상합니다. id 그리고 name 두 클래스 모두 동일한 테이블을 사용하여 매핑됩니다.(실제로 이것이 정확히 무슨 일이 일어나는지, 방금 다시 확인했습니다.)나는이 테이블을 가지고 있습니다 :

CREATE TABLE "problem" (
    "DTYPE" varchar(31) NOT NULL,
    "id" bigint(20) NOT NULL auto_increment,
    "name" varchar(255) default NULL,
    "levelOfUgliness" int(11) default NULL,
    PRIMARY KEY  ("id")
) AUTO_INCREMENT=2;

내 질문으로 돌아가서:

@ManyToOne 사람이 UglyProblem 클래스에 의해 상속될 것으로 예상합니다.

다른 모든 매핑된 필드는 상속되고 ManyToOne 관계에 대해 이 예외를 만들 이유가 없기 때문에 그럴 것으로 예상합니다.


응, 그거 봤어.실제로 제 경우에는 읽기 전용 솔루션을 사용했습니다.하지만 내 질문은 "왜..."였습니다 :).hibernate팀 구성원의 설명이 있는 것으로 알고 있습니다.도저히 찾을 수가 없어서 물어봤습니다.

이번 디자인 결정의 동기를 알고 싶습니다.

(내가 이 문제에 어떻게 직면했는지 관심이 있다면:나는 최대 절전 모드 3을 사용하여 빌드된 프로젝트를 상속받았습니다.그것은 Jboss 4.0이었습니다. 뭔가 + 최대 절전 모드가 이미 존재했습니다(모두 함께 다운로드하게 됩니다).이 프로젝트를 Jboss 4.2.2로 옮기고 있었는데 "@OneToMany mappedBy"의 상속된 매핑이 있고 이전 설정에서는 제대로 작동한다는 것을 알게 되었습니다...)

도움이 되었습니까?

해결책

Hibernate 팀의 현명한 결정이라고 생각합니다.덜 거만하고 왜 이런 방식으로 구현되었는지 명확하게 설명할 수 있지만 이것이 바로 Emmanuel, Chris 및 Gavin이 작동하는 방식입니다.:)

문제를 이해하려고 노력합시다.나는 당신의 개념이 "거짓말"이라고 생각합니다.먼저 그렇게 많다고 하더군요. 문제s는 다음과 연관되어 있습니다. 사람들.그런데 당신이 그런 말을 하더군요. 사람 많이있다 추악한 문제s (그리고 다른 것과 관련이 없습니다 문제에스).그 디자인에 뭔가 문제가 있어요.

데이터베이스에 어떻게 매핑될지 상상해 보세요.단일 테이블 상속이 있으므로 다음과 같습니다.

          _____________
          |__PROBLEMS__|          |__PEOPLE__|
          |id <PK>     |          |          |
          |person <FK> | -------->|          |
          |problemType |          |_________ |
          -------------- 

최대 절전 모드는 어떻게 데이터베이스를 강제로 만들 것인가? 문제 오직 관련이 있다 사람들 만약 그렇다면 문제 유형 평등 UP인가요?그것은 해결하기 매우 어려운 문제입니다.따라서 이러한 종류의 관계를 원한다면 모든 하위 클래스가 자체 테이블에 있어야 합니다.그게 다야 @MappedSuperclass 하다.

추신.:못난 그림이라 죄송해요 :D

다른 팁

내 경우에는 SINGLE_TABLE 상속 유형을 사용하고 싶었기 때문에 @MappedSuperclass를 사용하는 것은 옵션이 아니었습니다.

그다지 깨끗하지는 않지만 작동하는 방법은 Hibernate 독점 기능을 추가하는 것입니다. @어디 @OneToMany 연관에 대한 절을 사용하여 쿼리에서 유형을 강제합니다.

@OneToMany(mappedBy="person")
@Where(clause="DTYPE='UP'")
private List< UglyProblem > problems;

불행하게도 Hibernate에 따르면 선적 서류 비치 "@MappedSuperclass로 매핑되지 않은 수퍼 클래스의 속성은 무시됩니다." 나도 이것에 부딪혔다.내 솔루션은 엔터티 빈 자체가 아닌 인터페이스를 통해 원하는 상속을 표현하는 것이었습니다.

귀하의 경우 다음을 정의할 수 있습니다.

public interface Problem {
    public Person getPerson();
}

public interface UglyProblem extends Problem {
}

그런 다음 추상 슈퍼클래스와 두 개의 엔터티 하위 클래스를 사용하여 이러한 인터페이스를 구현합니다.

@MappedSuperclass
public abstract class AbstractProblemImpl implements Problem {
    @ManyToOne
    private Person person;

    public Person getPerson() {
        return person;
    }
}

@Entity
public class ProblemImpl extends AbstractProblemImpl implements Problem {
}

@Entity
public class UglyProblemImpl extends AbstractProblemImpl implements UglyProblem {
}

추가 이점으로, 해당 인터페이스를 구현하는 실제 엔터티 Bean이 아닌 인터페이스를 사용하여 코딩하는 경우 나중에 기본 매핑을 더 쉽게 변경할 수 있습니다(호환성이 손상될 위험이 적음).

내 생각엔 당신이 주석을 달아야 할 것 같아요 문제 슈퍼클래스 @MappedSuperclass 대신에 @실재.

OneToMany mappedBy 문제를 수행하는 방법을 알아냈습니다.

원본 게시물의 파생 클래스 UglyProblem에서.콜백 메서드는 상위 클래스가 아닌 파생 클래스에 있어야 합니다.

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@ForceDiscriminator
public class Problem {

}

@Entity
@DiscriminatorValue("UP")
public class UglyProblem extends Problem {
    @ManyToOne
    private Person person;
}

@Entity
public class Person {
    @OneToMany(mappedBy="person")
    private List< UglyProblem > problems;
}

적어도 Hibernate를 사용하기 위한 비밀 소스를 찾았습니다. http://docs.jboss.org/hibernate/stable/annotations/api/org/hibernate/annotations/ForceDiscriminator.html @ForceDiscriminator는 @OneToMany가 판별자를 존중하도록 만듭니다.

최대 절전 모드 주석이 필요합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top