JPA .find()变异实例

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JPA .find()变异实例相关的知识,希望对你有一定的参考价值。

我没想到这一点。

我有简单的JPA实体:

@Entity
@Audited(targetAuditMode = NOT_AUDITED)
@NamedQueries({
        @NamedQuery(
                name = "getShredInfoByDocUUID",
                query = "SELECT I FROM DocShreddingExtension I WHERE " +
                        "I.document2.UUID = :uuid"
        )
})
@EntityListeners({
        ShreddingListener.class,
})
@JsonIdentityInfo(
        generator = ObjectIdGenerators.PropertyGenerator.class,
        property = "id",
        scope = DocShreddingExtension.class
)
public class DocShreddingExtension implements Serializable {

    @OneToOne
    @JoinColumn(name = "code")
    private ShreddingType shreddingType;


    @Id
    @OneToOne
    @JoinColumn(name = "uuid")
    private Document2 document2;

    public DocShreddingExtension() {
    }

    public DocShreddingExtension(Document2 doc, ShreddingType type) {
        this();
        this.document2 = doc;
        this.shreddingType = type;
    }

    public ShreddingType getShreddingType() {
        return shreddingType;
    }

    public void setShreddingType(ShreddingType shreddingType) {
        this.shreddingType = shreddingType;
    }

    public Document2 getDocument2() {
        return document2;
    }

    public void setDocument2(Document2 document2) {
        this.document2 = document2;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        DocShreddingExtension that = (DocShreddingExtension) o;
        return Objects.equals(shreddingType, that.shreddingType) &&
                Objects.equals(document2, that.document2);
    }

    @Override
    public int hashCode() {

        return Objects.hash(shreddingType, document2);
    }
}

和DAO upsert方法:

public void upsert(DocShreddingExtension shreddingInfo) {
        DocShreddingExtension saved = entityManager.find(DocShreddingExtension.class, shreddingInfo);

        if (saved == null)
            entityManager.persist(shreddingInfo);
        else
            entityManager.merge(shreddingInfo);
    }

Document2模型类:

@Table(name = "document")
@Entity
@Audited
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonIdentityInfo(
        generator = ObjectIdGenerators.IntSequenceGenerator.class,
        scope = Document2.class
)
public class Document2 implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "doc_uuid")
    private long id;

    @Column(name = "uuid")
    private String UUID;

    @Column(name = "extId")
    private String extId;

    @ManyToOne(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
    @JoinColumn(name = "documentType")
    private DocType docType;

    @OneToMany(mappedBy = "document2", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Set<DocVersion> docVersions;

    @Column(name = "entityState")
    @Enumerated(EnumType.STRING)
    private EDocState eDocState;

    @ManyToOne
    @JoinColumn(name = "party_id")
    private PartyKind partyContainer;

    @OneToMany(mappedBy = "rootDoc", cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    private List<RelatedDoc> relatedDocs;

    @ElementCollection
    @CollectionTable(name = "product_instance", joinColumns = @JoinColumn(name = "doc_uuid"))
    @Column(name = "productInstance")
    private List<String> productInstanceIds;

    public int change;

    public Document2() {
        this.docVersions = new HashSet<>();
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getUUID() {
        return UUID;
    }

    public void setUUID(String UUID) {
        this.UUID = UUID;
    }

    public String getExtId() {
        return extId;
    }

    public void setExtId(String extId) {
        this.extId = extId;
    }

    public DocType getDocType() {
        return docType;
    }

    public void setDocType(DocType docType) {
        this.docType = docType;
    }

    public Set<DocVersion> getDocVersions() {
        return docVersions;
    }

    public void setDocVersions(Set<DocVersion> docVersions) {
        this.docVersions = docVersions;
    }

    public EDocState geteDocState() {
        return eDocState;
    }

    public void seteDocState(EDocState eDocState) {
        this.eDocState = eDocState;
    }

    public void addDocVersion(DocVersion version) {
        this.docVersions.add(version);
    }

    public PartyKind getPartyContainer() {
        return partyContainer;
    }

    public void setPartyContainer(PartyKind partyContainer) {
        this.partyContainer = partyContainer;
    }

    public List<RelatedDoc> getRelatedDocs() {
        return relatedDocs;
    }

    public void setRelatedDocs(List<RelatedDoc> relatedDocs) {
        this.relatedDocs = relatedDocs;
    }

    public List<String> getProductInstanceIds() {
        return productInstanceIds;
    }

    public void setProductInstanceIds(List<String> productInstanceIds) {
        this.productInstanceIds = productInstanceIds;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Document2 document2 = (Document2) o;
        return Objects.equals(UUID, document2.UUID);
    }

    @Override
    public int hashCode() {

        return Objects.hash(UUID);
    }
}

我的意图是检查实体是否已存在于数据库中并基于该实体保存或合并它。

发生的事情是找到实例,所以设置了'saved'但是'shreddingInfo'改变了对'saved'实例的更改,所以当我调用.merge()时,没有任何东西可以合并。

问题是为什么实体管理器在.find()方法中更改参数?我想这不是故意的。

答案

find方法期望主键作为第二个参数。但你通过了实体!

这导致了这种意想不到的行为。

您的映射不正确您必须在拥有共享主键时使用@PrimaryKeyJoinColumn:

public class DocShreddingExtension implements Serializable {

    @Id
    private String uuid;

    @OneToOne
    @JoinColumn(name = "code")
    private ShreddingType shreddingType;


    @OneToOne
    @PrimaryKeyJoinColumn
    private Document2 document2;

}

现在你可以用uuid调用find。

在这里找到更多信息:http://websystique.com/hibernate/hibernate-one-to-one-unidirectional-with-shared-primary-key-annotation-example/

以上是关于JPA .find()变异实例的主要内容,如果未能解决你的问题,请参考以下文章

三 JPA复杂查询的几种方式

Eclipselink 未检测到脏实体

JPA EntiityManager.find方法

有关JSF-JPA集成报 Could not find a setter for property message in class ..问题

何时将 EntityManager.find() 与 EntityManager.getReference() 与 JPA 一起使用

mvn命令异常:An error has occurred in Javadoc report generation: Unable to find javadoc command异常已解决(代码片段