@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 person 被 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 类有归档 idname 并且两个类都使用同一个表进行映射。(事实上​​,这正是发生的情况,我刚刚又检查了一遍)。我有这张表:

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 person 被 UglyProblem 类继承。

我希望如此,因为所有其他映射字段都是继承的,并且我看不出有任何理由为 ManyToOne 关系制定此例外。


是的,我看到了。事实上,我对我的案例使用了只读解决方案。但我的问题是“为什么......”:)。我知道 hibernate 团队的一名成员给出了解释。我找不到它,这就是我问的原因。

我想找出这个设计决定的动机。

(如果您对我如何面对这个问题感兴趣:我继承了一个使用 hibernate 3 构建的项目。这是 Jboss 4.0.something + hibernate 已经在那里了(你可以一起下载它)。我正在将此项目移至 Jboss 4.2.2,我发现存在“@OneToManymappedBy”的继承映射,并且它在旧设置上运行良好...)

有帮助吗?

解决方案

我认为这是 Hibernate 团队做出的明智决定。他们可以不那么傲慢,并清楚地说明为什么要这样实施,但这正是伊曼纽尔、克里斯和加文的工作方式。:)

让我们尝试理解这个问题。我认为你的概念是“谎言”。首先你说这么多 问题s 关联到 人们. 。但是,然后你说那一个 有很多 丑陋的问题s(并且不与其他 问题s)。这个设计有问题。

想象一下它将如何映射到数据库。您有一个表继承,因此:

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

hibernate将如何强制数据库使 问题 仅与 人们 如果它是 问题类型 等于UP吗?这是一个非常难解决的问题。因此,如果您想要这种关系,每个子类都必须位于它自己的表中。就是这样 @MappedSuperclass 做。

附:抱歉画得丑了:D

其他提示

就我而言,我想使用 SINGLE_TABLE 继承类型,因此使用 @MappedSuperclass 不是一个选项。

虽然不是很干净,但有效的方法是添加 Hibernate 专有的 @在哪里 @OneToMany 关联子句以强制查询中的类型:

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

不幸的是,根据 Hibernate 文档 “由于@mappedsuperclass被忽略,超级阶级的属性未映射。”我也反对这个。我的解决方案是通过接口而不是实体 bean 本身来表示所需的继承。

对于您的情况,您可以定义以下内容:

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 映射问题。

在原始帖子的派生类 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 尊重鉴别器

需要 Hibernate 注解。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top