【问题标题】:Hibernate Entity Class maps to two different TablesHibernate Entity Class 映射到两个不同的表
【发布时间】:2015-11-19 23:29:55
【问题描述】:

我正在尝试将我的 @Entity 对象映射到它们各自的类,其中一个是另一个的参数。

简单地说,我有这样的东西:

@Entity
@Table(name="TableA")
public class ClassA {
    @Id
    private long id;

    private String paramA;

    private ClassB classB;

    // getters and setters here
}

ClassB 看起来像:

@Entity
@Table(name="TableB")
public class ClassB {
    @Id
    private long classAId;

    private String paramB;

    // getters and setters here
}

为了保存我正在使用接口 - (我怀疑这是我的问题还是我使用它的方式是我的问题?)

@Transactional
public interface ClassADao extends JpaRepository<ClassA, Integer> {

}

在我的数据库中,ClassA 中的所有参数都映射到一个对应的表,除了 ClassB,它的参数都匹配到 ClassB 的不同表。我是 Hibernate 的新手,希望它将 ClassB 的参数映射到正确的表。但是,它似乎试图将 ClassB 映射到表中 ClassA 的列,从而给我这个错误:

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'classB' in 'field list'
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
    at com.mysql.jdbc.Util.getInstance(Util.java:387)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:941)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3870)

我的问题是,有没有办法(最好通过注释)告诉 Hibernate 将 ClassB 中的参数映射到它自己的表?我曾尝试使用@SecondaryTable,但没有奏效。

提前致谢!

【问题讨论】:

  • 我想知道是否需要为 ClassB 创建不同的 JpaRepository 接口并分别保存?我希望有级联效应,但也许这是不可能的?
  • 你也可以给表结构,还是让hibernate生成它?从第一眼看,你错过了@OneToOne 注释,它告诉休眠你有关系。您可以查看mkyong.com/hibernate/…库存有库存详情。
  • +1 用于提供表格结构。您尚未在代码中定义实体 A 和 B 之间的任何关系,因此 Hibernate/JPA 无法正确映射它们。您必须通过 JPA 注释(@OneToOne@OneToMany 等)来做到这一点。你可以用谷歌搜索 JPA 教程。关于你的 dao ......没有必要让它成为 @Transactional(Spring 数据会处理这个问题),因为你的 id 很长,你应该扩展 JpaRepository&lt;ClassA, Long&gt;
  • @NenadBozic - 表结构模仿对象。所以我会使用带有列 id、paramA 的 TableA 和带有 paramB 的 TableB。
  • @NenadBozic - 是的,似乎缺少 OneToOne 映射。做更多的研究显示了一些方法来做到这一点。我会尽快添加我的做法,如果您有更好的方法,请作为答案。

标签: java spring hibernate spring-data


【解决方案1】:

在对此发表评论的人的帮助下,我想出了以下解决方案:

@Id 
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;

@OneToOne(cascade = {CascadeType.ALL})
@PrimaryKeyJoinColumn
private ClassB classB;

public setClassB(ClassB classB) {
    this.classB = classB;
    this.classB.setClassA(this);
}

并像这样编辑 ClassB:

@Entity
@Table(name="TableB")
public class ClassB {
    @MapsId
    @OneToOne
    @JoinColumn
    private ClassA classA

    private String paramB;

    // getters and setters here - including for ClassA

}

现在当我调用 Spring 注入 ClassADao.save(classA) 时,ClassB 也会免费正确保存在数据库中。

【讨论】:

  • 很高兴知道是否有更好的解决方案。这就是我想出的。
  • 目前还没有,不过如果可以选择使用 Groovy,我正在开发一个工具包来自动化其中的大部分内容。 blog.chrylis.com
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-12
  • 2017-11-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多