【问题标题】:@ManyToOne Relation with Join table (nullable = false)@ManyToOne 与联接表的关系(可为空 = false)
【发布时间】:2018-09-04 13:41:12
【问题描述】:

尝试在TestEntityTestAttr 之间的单独表中创建@ManyToOne 关系得到错误响应:

org.hibernate.PropertyValueException: not-null property references a null or transient value : com.test.TestEntity.testAttr; nested exception is javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value : com.test.TestEntity.testAttr

这是有问题的实体:

@Table(name = "test_table")
public class TestEntity{

  @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
  @JoinTable(name = "test_attr_test_entity", joinColumns = {@JoinColumn(name = "test_entity_id", nullable = false, updatable = false)},
      inverseJoinColumns = {@JoinColumn(name = "test_attr_id", nullable = false, updatable = false)})
  private TestAttr testAttr;
  .
  .
  .
 }

当更改为@ManyToMany 时,它可以正常工作。

持久化代码:

testEntityRepository.save(testEntity)

【问题讨论】:

  • 可能您正试图保留一个TestEntity,其testAttr 属性为null,但我们确实需要一个minimal reproducible example 来确定。另外,为什么要使用连接表来建立多对一关系?它是允许的,但它很少是好的形式。
  • 实际上是的,我正在尝试保留一个没有 testAttr 的 TestEntity,并且默认情况下 @ManyToOne 关系应该是可选的。那么为什么我不能持久化一个带有 null testAttr 的 TestEntity 呢?
  • 可以添加实体代码吗?
  • 1.为什么要为 @ManyToOne 关系创建连接表。 2. 如果你真的想创建一个,那么你不能持久化TestEntity 为空的testAttr,因为你已经在name = "test_attr_id", nullable = false,...3 中指定了它。也许只是写下你想要完成的事情,以便我们重新考虑并提供一些解决方案。
  • 1.我需要另一个表,因为在大多数情况下不会有 testAttr,而且我不想要一个大部分为空值的列,2。我只想确保在表“test_attr_test_entity”中不允许空值。

标签: java mysql database hibernate jdbc


【解决方案1】:

我想你应该喜欢this 的例子。如果您想将其中的内容应用到您的项目中,您的实体可能如下所示:


测试实体

@Entity
public class TestEntity {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne
    private TestAttr testAttr;
...

测试属性

@Entity
public class TestAttr {

    @Id
    @GeneratedValue
    private Long id;
...

使用 Spring Data 存储库进行持久化的示例:

TestAttr attr = new TestAttr();

testAttrRepository.save(attr);

TestEntity entity1 = new TestEntity();
TestEntity entity2 = new TestEntity();

entity1.setTestAttr(attr);
entity2.setTestAttr(attr);

testEntityRepository.save(entity1);
testEntityRepository.save(entity2);

表格

正如你现在看到的,TestEntity 在数据库中有它的 testAttr 的 ID:

注意 这是一种单向的 OneToMany 关系。 (TestEntity 引用了它的 testAttr,但 TestAttr 没有它的 testEntities 列表

您可以根据需要使用级联类型调节 repo 方法的行为。 希望我有所帮助:)

【讨论】:

  • 实际上我需要将关系放在一个单独的表中。而且我不知道为什么 (name = "test_attr_id", nullable = false,...) 在这种情况下会阻止我在没有 testAttr 的情况下保留类型为 TestEntity 的实体。
  • @MohamedAhmedTaherMohamed 如果你有这个关系的单独表并且你用 testAttr 持久化 TestEntity 它将在这个表中创建具有 testEntity id 和 testAttr id 的行。如果您不想在此表中包含任何空值,那么您不能在没有另一个实体的情况下保留一个实体。
猜你喜欢
  • 2014-11-01
  • 1970-01-01
  • 2023-01-11
  • 2021-06-30
  • 1970-01-01
  • 1970-01-01
  • 2014-11-15
  • 1970-01-01
  • 2011-09-15
相关资源
最近更新 更多