Java 使用Hibernate Envers的复合表
我有一个应用程序,它有一个包含一个额外列的复合表。在添加Hibernate Envers@Audited之前,一切都很好 org.hibernate.MappingException:无法读取no.pack.response.ResponseDomainCode中responseDomainCodes的mapped by属性 如果有必要,我很乐意提供更详细的信息,但是,目前我不确定什么是相关的 这些表看起来像这样,是一个非常标准的复合键表,有一个额外的列 数据库模式 ResponseDomain.java ResponseDomainCodeId.javaJava 使用Hibernate Envers的复合表,java,hibernate,jpa,hibernate-envers,Java,Hibernate,Jpa,Hibernate Envers,我有一个应用程序,它有一个包含一个额外列的复合表。在添加Hibernate Envers@Audited之前,一切都很好 org.hibernate.MappingException:无法读取no.pack.response.ResponseDomainCode中responseDomainCodes的mapped by属性 如果有必要,我很乐意提供更详细的信息,但是,目前我不确定什么是相关的 这些表看起来像这样,是一个非常标准的复合键表,有一个额外的列 数据库模式 ResponseDomain
在@adamw的帮助下,我通过更改映射成功地解决了这个问题 生成了一个具有自己唯一ID的表,而不是使用复合键
+----------------------+------------+
| RESPONSE_DOMAIN_CODE | TYPE |
+----------------------+------------+
| id | PK(BIGINT) |
| response_domain_id | BIGINT |
| code_id | BIGINT |
| rank | VARCHAR |
+----------------------+------------+
现在,我不再使用@Embeddedable和@EmbeddedId,而是在两侧使用@ManyTone和@OneToMany注释,并基于ResponseDomain进行查询
这将在类似这样的关系中使用Hibernate Envers启用完整版本审核控制
我希望这会在某个时候对某人有所帮助。我认为Envers被复合主键弄丢了-可能是个bug。感谢您的快速响应。你对如何解决这个bug有什么想法吗?我可以补充一点,如果我删除ResponseDomain和代码中的映射,它工作得很好,但是关系变得很奇怪。如果我将@ManyToOne从responsedMainCodeId.java移动到responsedMainCode.java.Ah,它也可以工作。您在嵌入式id中有一个关系。我很确定这还不受支持。不确定是否有任何解决办法。。。除了有一个普通的id,比如长的。将@NotAudited添加到@OneToMany似乎可以解决这个问题。有没有更好的方法来映射这一点?那么你就没有审计了。正如我所写的,我认为Envers在嵌入式id中没有处理关系的功能,所以如果你想审计这个,我没有比代理id更好的主意。
@Entity
@Table(name = "responseDomain")
public class ResponseDomain implements Serializable {
@Id
@Column(name = "responseDomain_id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne
@JoinColumn(name = "respons_kind_id")
private ResponseKind responseKind;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.responseDomain", cascade = CascadeType.ALL)
private Set<ResponseDomainCode> responseDomainCodes = new HashSet<>();
//Omitted rest.
}
@Entity
@Table(name = "code")
public class Code implements Serializable {
@Id
@Column(name = "code_id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String category;
private String code;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.code", cascade = CascadeType.ALL)
private Set<ResponseDomainCode> responseDomainCodes = new HashSet<>();
//Omitted rest
}
@Entity
@Table(name = "responseDomain_code")
@AssociationOverrides(value = {
@AssociationOverride(name = "pk.responseDomain",
joinColumns = @JoinColumn(name = "responseDomain_id")),
@AssociationOverride(name = "pk.code",
joinColumns = @JoinColumn(name = "code_id"))
})
public class ResponseDomainCode implements Serializable {
@EmbeddedId
private ResponseDomainCodeId pk = new ResponseDomainCodeId();
@Column(name = "rank")
private String rank;
public ResponseDomainCodeId getPk() {
return pk;
}
public void setPk(ResponseDomainCodeId pk) {
this.pk = pk;
}
public String getRank() {
return rank;
}
public void setRank(String rank) {
this.rank = rank;
}
@Transient
public ResponseDomain getResponseDomain() {
return getPk().getResponseDomain();
}
public void setResponseDomain(ResponseDomain responseDomain) {
this.getPk().setResponseDomain(responseDomain);
}
@Transient
public Code getCode() {
return getPk().getCode();
}
public void setCode(Code code) {
this.getPk().setCode(code);
}
//Omitted rest
}
@Embeddable
public class ResponseDomainCodeId implements Serializable {
@ManyToOne
private ResponseDomain responseDomain;
@ManyToOne
private Code code;
public ResponseDomainCodeId() {
}
public ResponseDomain getResponseDomain() {
return responseDomain;
}
public void setResponseDomain(ResponseDomain responseDomain) {
this.responseDomain = responseDomain;
}
public Code getCode() {
return code;
}
public void setCode(Code code) {
this.code = code;
}
//Omitted rest
}
+----------------------+------------+
| RESPONSE_DOMAIN_CODE | TYPE |
+----------------------+------------+
| id | PK(BIGINT) |
| response_domain_id | BIGINT |
| code_id | BIGINT |
| rank | VARCHAR |
+----------------------+------------+