I have a parent child '@OneToMany' relation with the one side as owner. The relation is bidirectional. The reference table 'ParentChild' has a composite key (parentId, childId) and has an additional attribute 'name'. All changes should be audited by envers, therefore we have choosen the owner side on the parent side that adding and removing a child creates a revision of the parent. But generating the DDL throws the following exception:
Envers tries to generate the ParentChild_AUD table containing the composite key and the audited fields but it also tries to add two columns parent_id and child_id which conflicts with the composite key. Is this a bug or do I something wrong? Thanks for your help! Cheers Andy Generated DDL:
<?xml version="1.0" encoding="UTF-8"?>
<hibernate-mapping auto-import="false">
<class entity-name="com.comfone.audit.test.audittest.data.ParentChild_AUD" discriminator-value="ParentChild" table="parent_child_AUD" abstract="false">
<composite-id name="originalId">
<key-property name="childId" type="long">
<column name="child_id" length="255" scale="2" precision="19"/>
</key-property>
<key-property name="parentId" type="long">
<column name="parent_id" length="255" scale="2" precision="19"/>
</key-property>
<key-many-to-one type="integer" class="org.hibernate.envers.DefaultRevisionEntity" name="REV">
<column name="REV"/>
</key-many-to-one>
</composite-id>
<property insert="true" update="false" name="REVTYPE" type="org.hibernate.envers.internal.entities.RevisionTypeType"/>
<property insert="true" update="false" name="name" type="string">
<column name="name" length="255" scale="2" precision="19"/>
</property>
<property insert="false" update="false" name="child_id" type="long">
<column name="child_id" length="255" scale="2" precision="19"/>
</property>
<property insert="true" update="false" name="parent_id" type="long">
<column name="parent_id" length="255" scale="2" precision="19"/>
</property>
</class>
</hibernate-mapping>
Parent.java:
@Entity
@Audited
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@EqualsAndHashCode(of = {"id"})
public class Parent implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@AuditMappedBy(mappedBy = "parent")
@Builder.Default
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "PARENT_ID", insertable = false, updatable = false)
private Set<ParentChild> parentChildren = new HashSet<>();
@Version
@Setter(AccessLevel.NONE)
private Long version;
public void addParentChild(ParentChild parentChild) {
parentChild.setParent(this);
this.parentChildren.add(parentChild);
}
public void removeParentChild(ParentChild parentChild) {
parentChild.setParent(null);
this.parentChildren.remove(parentChild);
}
}
ParentChild.java:
@Entity
@Audited
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@EqualsAndHashCode(of = {"parentChildId"})
public class ParentChild implements Serializable {
@EmbeddedId
private final ParentChildId parentChildId = new ParentChildId();
private String name;
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@MapsId("parentId")
@JoinColumn(insertable = false, updatable = false)
private Parent parent;
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@MapsId("childId")
@JoinColumn(insertable = false, updatable = false)
private Child child;
@Version
@Setter(AccessLevel.NONE)
private Long version;
}
Child.java:
@Entity
@Audited
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@EqualsAndHashCode(of = {"id"})
public class Child {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
Source code: https://github.com/hotkeeper/jpa-envers-test |