JPA .find()变异实例

问题描述 投票:0回答:1

我没想到这一点。

我有简单的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()方法中更改参数?我想这不是故意的。

hibernate jpa find
1个回答
0
投票

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/

© www.soinside.com 2019 - 2024. All rights reserved.