Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate多通关联错误_Java_Hibernate_Jpa - Fatal编程技术网

Java Hibernate多通关联错误

Java Hibernate多通关联错误,java,hibernate,jpa,Java,Hibernate,Jpa,我整天都在努力在Java/JPA Hibernate中实现一个简单的ForeignKey-Manytone关联。。。没有成功。现在真的是寻求帮助的时候了;- 我有两个数据库表,如下所示: 请看这里: 还有像这样的物体: @Entity @Table(name = "sa_s_cat") public class SCat implements Serializable { @Id private int catId; private String catSuffix; private Stri

我整天都在努力在Java/JPA Hibernate中实现一个简单的ForeignKey-Manytone关联。。。没有成功。现在真的是寻求帮助的时候了;-

我有两个数据库表,如下所示:

请看这里:

还有像这样的物体:

@Entity
@Table(name = "sa_s_cat")
public class SCat implements Serializable {

@Id
private int catId;
private String catSuffix;
private String catDesc;
private Lkzs lkz;
private Date cdate;
private String cuser;
...
@Entity
@Table(name = "sa_s_cat")
public class SCat implements Serializable {

@Id
private int catId;
private String catSuffix;
private String catDesc;
private Lkzs lkz;
private Date cdate;
private String cuser;
...
我收到这个错误信息:

...
2014-07-11 09:16:32,649 [main] DEBUG org.hibernate.engine.jdbc.internal.JdbcServicesImpl - configure() - JDBC version : 4.0
2014-07-11 09:16:32,665 [main] TRACE org.hibernate.engine.jdbc.cursor.internal.StandardRefCursorSupport - supportsRefCursors() - JDBC DatabaseMetaData class does not define supportsRefCursors method...

同时,我搜索了很多论坛,阅读了文档和教程。。。因此,这实际上应该是可行的。

映射对象而不是列 问题在于,您已经将catId外键的同一DB列有效地映射到实体中的两个字段。您已经将其直接映射为图元int作为catId,还将对象关系映射为SCat cat

在JPA中,您必须试着忘记DB实现,而考虑对象。一个SSubCat有一个SCat,好的,所以给SSubCat添加一个SCat类型的字段。现在,在注释上,您将考虑如何在数据库中实现这一点。您有一个名为catId的外键列,这是您用@JoinColumn指定的

如果您试图同时指定基元列和对象关系,那么JPA不知道在持久化对象时选择哪个。正如您所发现的,纠正这种情况的一种方法是将其中一个字段指定为不可插入或不可更新。JPA将在从数据库检索时填充这两个字段,但当您保存回DB时,它将只保存仍然可更新的字段的值

像这样的一列有两个字段的另一个问题是,它们很快就会失去同步。如果调用setCat更改SCat对象,则catId仍然是旧SCat的id。您必须在setter中添加手动代码,以使两个字段保持同步。你不会真的想要这个,除非你有一些奇怪的要求,这意味着你必须这样做。您可能不需要,只需映射对象即可

双向一对多 使用JPA,更常见的是将其映射为如下所示的双向关系

@Entity
@Table(name = "sa_s_cat")
public class SCat implements Serializable {

  @Id
  private int catId;

  // mappedBy = the field in the other class that is the ManyToOne side
  @OneToMany(mappedBy="cat")
  private List<SSubCat> subCategories;


@Entity
@Table(name = "sa_s_subcat")
public class SSubCat implements Serializable {

  @Id
  private int subcatId;

  // The join column is the foreign key column in the DB
  @ManyToOne
  @JoinColumn(name = "catId")
  private SCat cat;

虽然我会选择双向关系

经过长时间的反复试验,我找到了一个解决办法

我从数据库中删除了外键定义,并更改了代码,如下所示:

但这又引出了一些问题,我希望有人能向我解释:

必须在数据库中定义外键才能使用hibernate/JPA实现映射,还是只能在代码中进行映射?我更愿意这样做

上述解决方案是否符合JPA?我不这么认为-

当然,为什么这个解决方案有效


发布异常的完整堆栈跟踪。尝试连接到服务器时似乎出现配置问题database@JBNizet:堆栈跟踪显示没有其他错误@TritonMan:配置和数据库连接正常。我可以毫无问题地检索subcat和cat。但是,当我集成foreignkey关联时,错误就出现了。这并不是你发布的堆栈跟踪。它只是控制台中的调试输出。完整堆栈跟踪将显示类名和行号,并指出错误发生的位置,并提供错误说明。此外,还有。。。最后暗示还有更多。谢谢,但据我所知,两个实体的关系只有在你想有双向关联的情况下才是必要的。但我想要的是单向的。DB中的ForeignKey列是catId我尝试了你的建议,并在cat中添加了一个OMANY。。。同样的行为。反正是Thx!当您使用单向时,您不必告诉JPA这两个表的列名。请阅读我用您的单向示例测试过的内容,但行为相同。我在上面的帖子中更新了跟踪。我已经读过维基百科了。同样的东西写在那里,但它不起作用…@ShadowRay如果两个列名相同,则不需要指定它们,在本例中它们是相同的。如果它们有不同的名称,则必须使用name和referencedColumnName属性对它们进行命名。不过,命名两者并没有什么坏处。只在代码中映射是什么意思?在数据库中需要有链接它们的东西。JPA还能如何计算出哪些行是相关的?不过,您不需要将该外键列指定为实体中的字段。您只需要将其命名为多对一关系中的联接列。事实上,这是您的问题。如果将catId外键列指定为实体中的字段,并将其命名为多对一上的联接列,则实际上已将同一DB列映射到实体中的两个字段。这就是为什么insertable,updateable修复了它,因为它告诉JPA不要担心多对一字段的持久化,所以对于持久化,它会将值保存在catId中,而不是cat中。@BenThurley:这正是我想要的。JPA不应该担心持久性。我也没有在外键上定义persist和update操作。我只需要显示关联c的关联
在非常感谢。你真是太不得体了。JPA是一种ORM工具,旨在将对象映射到关系数据库。如果映射对象,仍然可以通过执行诸如getSCat.getId之类的操作而不是getCatId来获取id。
@Entity
@Table(name = "sa_s_subcat")
public class SSubCat implements Serializable {

  @Id
  private int subcatId;

  @ManyToOne
  @JoinColumn(name="catId", referencedColumnName="catId")
  private SCat cat;
@Entity
@Table(name = "sa_s_cat")
public class SCat implements Serializable {

@Id
private int catId;
private String catSuffix;
private String catDesc;
private Lkzs lkz;
private Date cdate;
private String cuser;
...
@Entity
@Table(name = "sa_s_subcat")
public class SSubCat implements Serializable {

@Id
private int subcatId;
private int catId;
private String subcatSuffix;
private String subcatDesc;
private boolean subcatShowProd;
private boolean subcatShowComp;
private boolean subcatShowQual;
private boolean subcatShowDetail;
private Lkzs lkz;
private Date cdate;
private String cuser;
@ManyToOne(optional = false)
@JoinColumn(name = "catId", insertable = false, updatable = false)
private SCat cat;
...