【问题标题】:Hibernate and two classes mapped to single tableHibernate 和两个类映射到单个表
【发布时间】:2017-11-01 07:31:13
【问题描述】:

我有一个具有多个属性的表。 我想要两个类来访问这些(专有)属性。

@Entity
@Table(name = "MY_TABLE")
public class Foo {

...
    @Column
    @NotNull
    private String fooValue; 
}

@Entity
@Table(name = "MY_TABLE")
public class Bar {
...
    @Column
    private String barValue; 
...
}

基本上Bar 是表中一些 值的只读视图。 Foo 用于更新其他值,Bar 用于查看其他值(不是使用 Java 应用程序创建的)。

问题在于,当我尝试使用 Spring Data 存储库保存 Foo 时:

public interface FooRepository extends JpaRepository<Foo, Long> {
}

我收到 fooValue 设置为 null 的异常。我在日志中看到一个带有NULL 的插入fooValue。我对其进行了一点调试,当我从项目中完全删除 Bar 时,保存工作正常,当我再次添加它时,Foo 的保存停止工作。

所以对我来说,即使我尝试保存 Foo,Hibernate 也会选择 Bar 类。为什么?

我的堆栈是:Spring Boot 1.5.3、Spring Data、Hibernate 5.x

【问题讨论】:

  • 你也可以考虑只使用惰性获取:)

标签: java spring hibernate spring-boot spring-data


【解决方案1】:

坦率地说,我从未见过两个实体以这种方式映射同一张表。

通常你会定义一个继承配置并从那里开始工作:

基础实体

@Entity
@Inheritance
@DiscriminatorColumn(name="TABLE_TYPE")
@Table(name="MY_TABLE")
public  class MyTable implements Serializable{
  @Id
  @GeneratedValue
  protected int id;
  ...
}

Foo 实体

@Entity
@DiscriminatorValue("FOO")
public class FooTable extends MyTable {
    @Column
    @NotNull
    private String fooValue; 
}

酒吧实体

@Entity
@DiscriminatorValue("BAR")
public class FooTable extends MyTable {
    @Column
    private String barValue; 
}

这是单表继承策略,似乎最适合您的情况。

【讨论】:

  • 是的,我想避免继承,因为这两个类没有太多共同点。数据在它们之间拆分,因此它们不会重叠。所以我认为更简单的方法是拥有两个完全不同的类。我仍然很困惑为什么hibernate不能区分它们。
  • 这种定义实体的方式绝对不在 JPA 规范中。 Hibernate .. 至少最新版本非常符合该规范.. 我在启动期间没有抱怨,但运行时行为似乎不可预测
【解决方案2】:

如果您想避免继承,您还可以使用 FOO 和 BAR 等适当字段构建两个不同的类,将它们设为 @Embeddable 并创建一个额外的类:

class SuperFoo {
   //make some ID

  @Embedded
  @Basic(fetch = FetchType.LAZY)
  Foo foo;

  @Embedded
  @Basic(fetch = FetchType.LAZY)
  Bar bar;
}

然后你就可以得到这些课程之一。在数据库中它看起来像一个普通的表。

【讨论】:

    猜你喜欢
    • 2010-12-12
    • 2012-02-06
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多