当前位置: 首页 > 知识库问答 >
问题:

Spring Data JPA中两个不同模式之间具有父子关系的持久化表

胥智
2023-03-14

我正在努力做,

ChildTable child = new ChildTable();
clild.setParentTwoID(prentTwoID);
ParentOne parentOne = new ParentOne();
parentOne.getChildTableList().add(childTable);
parentReposetory.save(parentOne);

其中,父母一在模式S1中,父母二在模式S2中与儿童表在一起。

家长一号。JAVA

@Data
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "ParentOne", schema = "S1")
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, scope = ParentOne.class)
public class ParentOne implements Serializable {

    private static final long serialVersionUID = 7502273069461829133L;

    @Id
    @Column(name = "ParentOneID", unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer parentOneID;

    @OneToMany(targetEntity = ChildTable.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "ParentOneID", nullable = false, insertable = false, updatable = false)
    private List<ChildTable> childTableList;
}

家长wo.java

@Data
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "ParentTwo", schema = "S2")
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, scope = ParentTwo.class)
public class ParentTwo implements Serializable {

    private static final long serialVersionUID = 7502273069461829133L;

    @Id
    @Column(name = "ParentTwoID", unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer parentTwoID;

    @OneToMany(targetEntity = ChildTable.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "ParentTwoID", nullable = false, insertable = false, updatable = false)
    private List<ChildTable> childTableList;
}

ChildTable.java

@Data
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "ChildTable", schema = "S2")
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, scope = ChildTable.class)
public class ChildTable implements Serializable {

    private static final long serialVersionUID = -6331600489988183852L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ChildTableID", unique = true, nullable = false)
    private Integer childTableID;

    @Column(name = "ParentOneID")
    private Integer parentOneID;

    @Column(name = "ParentTwoID", nullable = false)
    @NotNull(message = "mandatory_field")
    private Integer parentTwoID;

}

这里ParentTwo已经被持久化了,我有它的Id。我将只保留ParentOne以及不同模式的子表。当我这么做的时候,我会犯这样的错误。

rg.springframework.dao.:无法执行语句;SQL[n/a];约束[null];嵌套异常org.hibernate.exception.ConstraintViolationExctive:无法执行语句

原因:com。微软sqlserver。jdbc。SQLServerException:无法将值NULL插入“ParentOneID”列、表“PT_Sample”。S2。可生育';列不允许空值。插入失败。

SQL错误:515,SQLState:23000

共有1个答案

徐嘉谊
2023-03-14

使用JPA时,需要允许JPA提供程序管理实体实例之间的关系。在给定的情况下,通过跟踪各种外键标识符来手动管理关系。因此,JPA提供程序无法设置外键列值。

基本问题似乎在于理解JPA(或任何其他ORM)是如何工作的。实体不是数据库表的逐列副本。它们需要被视为对象并建模,而不需要考虑底层数据库。实体属性到数据库列的映射应该留给JPA提供者。

以下实体模型将解决问题(为了简洁起见,删除了所有不必要的代码):

一个实体

@Entity
@Table(name="ParentOne", schema="S1")
public class ParentOne {
  @Id
  @Column(name="ParentOneID", unique=true, nullable=false)
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Integer id;

  @OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL, mappedBy="parentOne")
  private List<Child> children;

  public void addChild(final Child child) {
    if (children == null) {
      children = new ArrayList<>();
    }

    children.add(child);

    child.setParentOne(this);
  }
}

以下几点值得注意:

  1. 模式名(S1)与必须将实体实例持久化到的表名一起声明
  2. 与子实体的关系声明为集合,并注释为@OneToMany
  3. 持久性操作(保存、更新、删除)被级联到子实体实例(cascade=CascadeType.ALL)。这可以确保父实例上的持久性操作自动处理任何关联子实例上的适当操作

双亲实体

@Entity
@Table(name="ParentTwo", schema="S2")
public class ParentTwo {
  @Id
  @Column(name="ParentTwoID", unique=true, nullable=false)
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Integer id;

  @OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL, mappedBy="parentTwo")
  private List<Child> children;

  public void addChild(final Child child) {
    if (children == null) {
      children = new ArrayList<>();
    }

    children.add(child);

    child.setParentTwo(this);
  }
}

子实体

@Entity
@Table(name="ChildTable", schema="S2")
public class Child {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name="ChildTableID", unique=true, nullable=false)
  private Integer id;

  @ManyToOne(cascade=CascadeType.PERSIST)
  @JoinColumn(name="ParentOneID", nullable=false)
  private ParentOne parentOne;

  @ManyToOne(cascade=CascadeType.PERSIST)
  @JoinColumn(name="ParentTwoID", nullable=false)
  private ParentTwo parentTwo;

  void setParentOne(final ParentOne parentOne) {
    this.parentOne = parentOne;
  }

  void setParentTwo(final ParentTwo parentTwo) {
    this.parentTwo = parentTwo;
  }
}

以下几点值得注意:

  1. 模式名称(S2)在表名称旁边声明。
  2. 与父表的关联被声明为对象实例,而不是原始列。

在此之后,以下代码将正常工作:

Child child = new Child();
...

ParentOne parentOne = new ParentOne();
ParentTwo parentTwo = new ParentTwo();
...

parentOne.addChild(child);
parentTwo.addChild(child);

parentOneRepository.save(parentOne);
 类似资料:
  • 问题内容: Book,User和Review说,我正在构建具有复杂模型的应用程序。 评论包含书籍和用户ID。为了能够搜索至少包含一个评论的“图书”,我已将“图书”设置为“评论”的父级,并且具有这样的路由。但是,我还需要找到撰写包含某些短语的评论的用户。 是否可以同时将书和用户作为评论的父级?有没有更好的方法来处理这种情况? 请注意,我无法更改数据建模的方式/不愿意这样做,因为数据已从持久性数据库传

  • 我刚刚开始使用activemq,我有一个关于追溯消费者的问题,为了启用此功能,您需要有一个持久的订阅。但是,在主题上启用和不启用追溯的持久订阅有什么区别?活跃的mq文档说。 http://activemq.apache.org/retroactive-consumer.html 追溯性使用者只是一个普通的 JMS Topic 使用者,它指示在订阅开始时,每次尝试都应该用于返回时间并发送使用者可能错

  • 问题内容: 我们有一个带有父子关系的表,希望对它进行排序。排序标准是这样的,以便在遍历结果时,与父ID匹配的行应该已经存在: 问题在于两个密钥都是字符串,因此按ID或PARENT_ID排序将无法解决问题。 问题答案: 对于Oracle,使用分层查询:

  • 问题内容: 这是一个关于如何将cookie从一个casperjs页持久化到另一个页面的问题。 所以基本上我得到了一个nodejs文件,该文件生成casperjs作为工作人员执行某些任务。一个是登录,一旦登录,我就将cookie存储在文件中。 当我产生下一个Casper工人时..我希望它使用Cookie而不是再次登录..这两种方法均 失败 : 第一: 当我生成worker capserjs时,我添加

  • 我使用JPA处理两个数据库,其中包含不同的对象模型。 persistence.xml 当我这样创建工厂时: 它工作得很好,但是使用unit_2中的所有类更新unit_1的数据库。工厂元模型。实体将包含所有4个类: my.package.items1.Class1_1 my.package.items1.Class1_2 my.package.items2.Class2_1 my.package.i

  • 我正在创建一个简单的社交图,用户可以在其中创建一个帖子,标记它,并对它进行评论。我用py2neo做模型。该模型具有和作为节点。用户在上、或。在我的例子中,单个用户可以在单个上创建多个或(就像其他任何社交网络一样)。根据我的模型,这需要多个或关系,但具有不同的属性。模型是这样建立的: 我运行以下操作来构建图形: 我希望有两个关系,如下所示: 但我看到事实并非如此: 那么,我的问题是双重的。(1)可以