0

我正在尝试使用 hibernate-panache 将数据持久化到OneToMany表 Feature 和 FeatureRole。创建了一个服务方法,输入将是List<Long>功能的 id 和String角色名称。我想插入 FeatureRole 表,其中包含每个功能(来自 id)和角色名称。

return Panache.withTransaction(() -> {
            return featuresRepository.findByIds(ids).collect().asList().onItem().transform(t -> {
                FeatureRole fr = new FeatureRole();
                fr.setRole_name("role name");
                for (Features fe: t) {
                    fr.setFeatures(fe);
                    fe.getFeatureRoles().add(fr);
                }
                return featureRoleRepository.persistAndFlush(fr).map(to -> fr);
            }).flatMap(t -> t);
        });

当我运行它时,发生了错误。说插入到 feature_role 表的特征没有被持久化。我们如何解决这个错误。

Caused by: java.util.concurrent.CompletionException: org.hibernate.PersistentObjectException: detached entity passed to persist: io.github.jithset.models.Features
                at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:331)
                at java.base/java.util.concurrent.CompletableFuture.uniApplyNow(CompletableFuture.java:670)
                at java.base/java.util.concurrent.CompletableFuture.uniApplyStage(CompletableFuture.java:658)
                at java.base/java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:2094)
                at java.base/java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:143)
                at org.hibernate.reactive.util.impl.CompletionStages.lambda$loop$5(CompletionStages.java:170)
                at com.ibm.asyncutil.iteration.AsyncTrampoline.lambda$asyncWhile$1(AsyncTrampoline.java:209)
                at com.ibm.asyncutil.iteration.AsyncTrampoline$TrampolineInternal.unroll(AsyncTrampoline.java:119)
                at com.ibm.asyncutil.iteration.AsyncTrampoline$TrampolineInternal.trampoline(AsyncTrampoline.java:101)
                at com.ibm.asyncutil.iteration.AsyncTrampoline$TrampolineInternal.access$200(AsyncTrampoline.java:84)
                at com.ibm.asyncutil.iteration.AsyncTrampoline.asyncWhile(AsyncTrampoline.java:192)
                at com.ibm.asyncutil.iteration.AsyncTrampoline.asyncWhile(AsyncTrampoline.java:209)
                at org.hibernate.reactive.util.impl.CompletionStages.loop(CompletionStages.java:169)
                at org.hibernate.reactive.util.impl.CompletionStages.loop(CompletionStages.java:186)
                at org.hibernate.reactive.session.impl.ReactiveSessionImpl.fire(ReactiveSessionImpl.java:1076)
                at org.hibernate.reactive.session.impl.ReactiveSessionImpl.firePersist(ReactiveSessionImpl.java:696)
                ... 67 more

功能角色

@Entity
@Table(name = "feature_role")
public class FeatureRole {

    @Id
    @SequenceGenerator(name = "featureRoleSeq", sequenceName = "featureRoleSeq", allocationSize = 1)
    @GeneratedValue(generator = "featureRoleSeq")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "features_id", nullable = false)
    @Getter @Setter
    @JsonbTransient
    private Features features;

    @Getter @Setter
    private String role_name;

}

特征

@Entity
@Table(name = "features")
@NoArgsConstructor
@ToString
public class Features {

    @Id
    @SequenceGenerator(name = "featureSequence", sequenceName = "featureSequence", allocationSize = 1)
    @GeneratedValue(generator = "featureSequence")
    @Column(name = "feature_id")
    @Getter @Setter
    public Long id;

    @Getter @Setter
    @NotBlank
    @Column(unique = true)
    public String name;

    @OneToMany(
            mappedBy = "features",
            cascade = CascadeType.ALL,
            orphanRemoval = true,
            fetch = FetchType.EAGER
    )
    @Getter @Setter
    private List<FeatureRole> featureRoles =new ArrayList<>();

    public Features(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    public static Features from(Row row) {
        return new Features(row.getLong("feature_id"), row.getString("name"));
    }`enter code here`
4

1 回答 1

0

根据您的映射,FeatureRole可以将 a 关联到单个Features(多对一)。在您的代码中,Features每次调用 fr.setFeatures(fe);.

这意味着只有Features循环中的最后一个将具有正确的关联,因为fr它只关联到单个元素。

假设 aFeatures可以有 many FeatureRole,您需要决定适用哪个用例:

1.一个FeatureRole可以有很多Features

然后它是一个双向多对多关联,您必须将映射重写为类似于:

...
class FeatureRole {
    ...
    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private List<Features> features;
    ...
    public void addFeature(Features features) {
     this.features.add( features );
     features.getFeatureRoles().add( this );
 }
...
class Features {
    ...
    @ManyToMany(mappedby="features")
    private List<FeatureRole> featureRoles =new ArrayList<>()
    ...
}

然后循环中的代码变为:

for (Features fe: t) {
    fr.addFeatures(fe);
}

2.一个单FeatureRole只能关联一个Features

然后需要改变循环的逻辑。但在这种情况下,我需要更多细节来帮助你。

于 2021-05-01T22:57:27.993 回答