【问题标题】:Search by two unique fields spring boot for uniqueness按两个唯一字段搜索 spring boot 的唯一性
【发布时间】:2020-06-26 08:59:06
【问题描述】:

我创建了一个子实体:

public class ChildEntity  {
   private Long bookNo;
   private String bookType;
}

这两个字段一起是唯一的。某种数据:

| No | Type      |
|----|-----------|
| 1  | Classical |
| 2  | Classical |
| 2  | Scifi     |
| 3  | Scifi     |
| 1  | Classical | (Error for uniqueness

我创建了这个实体来搜索父实体。

public class ParentEntity{
    @ManyToOne
    private ChildEntity child;    
    //and other fields here
}

此外,还有 2 个不同的父实体。他们必须是不同的实体,他们有几个不同的领域。但是这个子实体很常见。因此,我将使用这些子实体来比较/获取数据表之间的差异,因为该子实体中只有唯一区域。我可以通过该子实体字段获取数据表的差异。

我制作了 ManyToOne,因为许多不同的父母可以拥有同一个孩子。

我在这样的服务中创建父实体:

private createParentEntity(Dto dto){
    
    ParentEntity parent = new ParentEntity();
    //set other fields from dto
    parent.setAge(dto.getAge);
    
    ChildEntity child = new ChildEntity();
    child.setBookNo(dto.getBookNo());
    child.setBookType(dto.getBookType());
    
    parent.setChild(child);//here is problem , please look down
}

我的问题是,我发表评论的那一行。

相同的子实体可以来,所以当我保存父母时,它会再次尝试保存孩子并且会得到一个唯一的约束错误?我该怎么做?

因为最后我会使用spring data在父仓库里面这样搜索:

parentEntityRepository.findByChild(ChildEntity child);
@UniqueConstraints = {
    @UniqueConstraint(
         name = "uq_general_checklist_ordinal",
         columnNames = {"book_no", "book_type"}
    )
}
public class ChildEntity {
   @Id
   private Long bookNo;
    
   @Id
   private String bookType;
}

放置两个 ID 是否是一个好的解决方案?还是这里,我应该先救下孩子,看看它是否存在?

ChildEntity child =childRepository.findByBookNoAndBookType(
     dto.getBookNo(), 
     dto.getBookType()
);//if exists, set to parent. if not, create new and set it?

【问题讨论】:

    标签: java spring-boot spring-data unique-constraint spring-repositories


    【解决方案1】:

    我会这样做:“或者在这里,我应该先保存孩子并检查是否存在?”

    但是,无需先保存孩子,只需搜索具有新 ID 的孩子即可。这样,您可以避免 SQL 异常。如果它不存在,仍然不要救孩子。将其添加到父级并保存父级。因此,它将拯救孩子。如果存在,将其添加到新父级并保存父级。

    【讨论】:

    • 那么,对于子实体,您建议将3.字段作为id列?
    • 我不知道我是否理解你的问题,但我明白你所说的 ChildEntity 可能有多个父级。如果您现在询问将 ChildEntity id 放在 Parent 中,是的,它可以在我的回答中使用相同的方法。但是,即使您只是添加 ChildEntity 本身,Hibernate 也只会使用 Parent 中的 ID 列。
    • 我现在在 child 中有两列,bookno,booktype。您建议将 id 作为 3. 列?
    • 不!因为父母可以拥有同一个孩子,所以应该在 Parent 中引用孩子。通过您拥有的 Child 对象或通过子 ID。
    【解决方案2】:

    除非我想大量使用 Hibernate 的第一级缓存等,否则我在紧密的一对多场景中的 goto 方法已经变成了一种单向关系,但除了加载部分之外,所有的责任都由 Hibernate 承担自己动手。

    这使得它可以预测并节省大量时间来摆弄 Hibernate 以及由此产生的其他约定、人们的假设和其他框架的问题(例如递归 toString、equals、hashcode 方法,当你让它们自动生成/没有精心制作时) .

    为此我使用:

    @OneToMany
    @JoinColumn(insertable = false, updatable = false)
    

    在父级和子级的普通 id 列。

    【讨论】:

    • 如何插入子对象?因为我会收到父对象,所以也许新的子对象可以从这些父对象那里接收?
    • @msadasjwd 您有一个单独的 dao/repository 用于子对象,并通过它显式插入它们。您可以通过 parentRepository.findAllById(1) 检索具有当前子项的父项,然后确定您需要添加一个子项,因为它还没有,使用对父项的主键的引用来构造它 - 例如 child5 - 并插入它通过 childRepository.save(child5) 进入数据库。
    • 是的,为孩子单独存储库。因此,要比较 2 个父实体,首先我应该通过这两个字段从子存储库中获取子 ID。然后,使用父存储库,我将使用该 ID 进行搜索,例如 parentrepository.findAllByChildEntityId(Long id)
    猜你喜欢
    • 2017-09-13
    • 2018-02-07
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 2010-12-10
    • 2015-06-16
    • 1970-01-01
    • 2019-03-22
    相关资源
    最近更新 更多