我没想到这一点。
我有简单的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);
}
}
我的意图是检查实体是否已存在于数据库中,并根据该实体进行保存或合并。
发生的事情是找到实例以便保存&#39;已设置但是“粉碎信息”#39;更改已保存的&#39;例如,当我调用.merge()时,没有任何东西可以合并。
问题是为什么实体管理器在.find()方法中更改参数? 我想这不是故意的。
答案 0 :(得分: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。