Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.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
Spring boot SpringBoot级联类型所有vs合并和分离实体_Spring Boot_Jpa - Fatal编程技术网

Spring boot SpringBoot级联类型所有vs合并和分离实体

Spring boot SpringBoot级联类型所有vs合并和分离实体,spring-boot,jpa,Spring Boot,Jpa,我拥有以下实体: @Entity @Getter @Setter @NoArgsConstructor @RequiredArgsConstructor public class Link extends Auditable { @Id @GeneratedValue private Long id; @NonNull private String title; @NonNull private String url; @

我拥有以下实体:

@Entity
@Getter @Setter @NoArgsConstructor @RequiredArgsConstructor
public class Link extends Auditable {

    @Id
    @GeneratedValue
    private Long id;

    @NonNull
    private String title;


    @NonNull
    private String url;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "link")
    private List<Comment> comments = new ArrayList<>();

    @Transient
    @Setter(AccessLevel.NONE)
    private String userAlias ;

    public String getUserAlias() {

        if(user == null)
            return "";

        return user.getAlias();


    }

    @ManyToOne
    private User user;

    public Long getUser() {
        if(user == null)
            return -1L;

        return user.getId();
    }

    public void addComment(Comment c) {
        comments.add(c);
        c.setLink(this);

    }




}

@Entity
@Getter @Setter @NoArgsConstructor @RequiredArgsConstructor
public class Comment extends Auditable{

    @Id
    @GeneratedValue
    private Long id;

    @NonNull
    private String comment;

    @ManyToOne(fetch = FetchType.LAZY)
    private Link link;

    public Long getLink() {
        return link.getId();
    }


}
但是,如果我先保存注释:

Link link = new Link("Getting started", "url");
Comment c = new Comment("Hello!");
commentRepository.save(c);
link.addComment(c);
linkRepository.save(link);
我明白了

Caused by: org.hibernate.AnnotationException: @OneToOne or @ManyToOne on uk.me.dariosdesk.dariodemo.domain.Comment.link references an unknown entity: uk.me.dariosdesk.dariodemo.domain.Link
    at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:97) ~[hibernate-core-5.4.0.Final.jar:5.4.0.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processEndOfQueue(InFlightMetadataCollectorImpl.java:1815) ~[hibernate-core-5.4.0.Final.jar:5.4.0.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processFkSecondPassesInOrder(InFlightMetadataCollectorImpl.java:1759) ~[hibernate-core-5.4.0.Final.jar:5.4.0.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1646) ~[hibernate-core-5.4.0.Final.jar:5.4.0.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:287) ~[hibernate-core-5.4.0.Final.jar:5.4.0.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:903) ~[hibernate-core-5.4.0.Final.jar:5.4.0.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:934) ~[hibernate-core-5.4.0.Final.jar:5.4.0.Final]
将级联类型从ALL更改为MERGE似乎可以解决问题并接受这两种实现。(即:添加预先存在的注释或同时创建注释,然后通过链接保存)

1) 为什么会这样?
2) 在使用“合并”而不是“全部”时,有什么我应该注意的吗?

存储库保存方法检查实体是否存在。对于新实体,调用persist;对于persistend,调用merge

@Transactional
public <S extends T> S save(S entity) {

    if (entityInformation.isNew(entity)) {
        em.persist(entity);
        return entity;
    } else {
        return em.merge(entity);
    }
}
@Transactional
公共存储(S实体){
if(entityInformation.isNew(实体)){
em.persist(实体);
返回实体;
}否则{
返回em.merge(实体);
}
}
在第二个用例中,链接是新实体,因此调用persist()。使用CascadeType.ALL persist()将级联到注释实体。注释已持久化,需要合并,persist()失败

如果使用CascadeType,则MERGE persist()不会级联到注释。它不会失败

@Transactional
public <S extends T> S save(S entity) {

    if (entityInformation.isNew(entity)) {
        em.persist(entity);
        return entity;
    } else {
        return em.merge(entity);
    }
}