I want to add history to my entities and I am playing arround with hibernate Envers.
I have defined Handbook
and Chapter
classes with the coresponding 5 tables:
HANDBOOK
, HANDBOOK_AUD
, CHAPTER
, CHAPTER_AUD
and REVINFO
.
If there is no connection between the 2 entities, everithing works fine, but when I add oneToMany
relationship for HANDBOOK
and CHPATER
the application fails to start because of missing HANDBOOK_CHAPTER_AUD
table.
Thinking about it is absolutely fine to have that JoinTable, but the problem is how should define it.
Handbook entity:
@Entity
@Audited
@Getter
@Setter
@NoArgsConstructor
public class Handbook {
@Id
@SequenceGenerator(name = "HANDBOOK_ID_SEQUENCE", sequenceName = "HANDBOOK_ID_SEQUENCE", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "HANDBOOK_ID_SEQUENCE")
private Long id;
private String title;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "HANDBOOK_ID")
@AuditJoinTable(name = "REV_HANDBOOK_CHAPTER")
private Set<Chapter> chapters;
}
Chapter entity:
@Entity
@Audited
@Getter
@Setter
@NoArgsConstructor
public class Chapter {
@Id
@SequenceGenerator(name = "CHAPTER_ID_SEQUENCE", sequenceName = "CHAPTER_ID_SEQUENCE", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CHAPTER_ID_SEQUENCE")
private Long id;
private String name;
@Column(name = "HANDBOOK_ID")
private Long handbookId;
}
Tables deffinition:
<createTable tableName="REVINFO">
<column name="rev" type="integer">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="revtstmp" type="bigint"/>
</createTable>
<!-- Hibernate Envers need this seq exact to increase the revision number for versioned entities-->
<createSequence sequenceName="HIBERNATE_SEQUENCE"
startValue="1"
incrementBy="1"/>
<createTable tableName="HANDBOOK">
<column name="ID" type="bigint">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="TITLE" type="varchar2(128 char)"/>
</createTable>
<createTable tableName="REV_HANDBOOK">
<column name="ID" type="bigint"/>
<column name="TITLE" type="varchar2(128 char)"/>
<column name="REV_ID" type="integer">
<constraints foreignKeyName="FK_HANDBOOK_REV"
references="REVINFO(REV)"/>
</column>
<column name="REV_TYPE" type="smallint"/>
</createTable>
<!-- CHAPTER TABLES -->
<createTable tableName="CHAPTER">
<column name="ID" type="bigint">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="NAME" type="varchar2(128 char)"/>
<column name="HANDBOOK_ID" type="integer">
<constraints foreignKeyName="FK_CHAPTER_HANDBOOK_ID"
references="HANDBOOK(ID)"/>
</column>
</createTable>
<createTable tableName="REV_CHAPTER">
<column name="ID" type="bigint"/>
<column name="NAME" type="varchar2(128 char)"/>
<column name="HANDBOOK_ID" type="integer">
<constraints foreignKeyName="FK_CHAPTER_AUD_HANDBOOK_ID"
references="HANDBOOK(ID)"/>
</column>
<column name="REV_ID" type="integer">
<constraints foreignKeyName="FK_CHAPTER_REV"
references="REVINFO(REV)"/>
</column>
<column name="REV_TYPE" type="smallint"/>
</createTable>
NOTE: I have edited some namings according to the hibernate envers documentation:
org:
hibernate:
envers:
audit_table_prefix: REV_
audit_table_suffix: ~ # No suffix
revision_field_name: REV_ID
revision_type_field_name: REV_TYPE
I have found out a sollution based on the series of errors hibernate gave me after running the code. Here is how I defiend the revision join table:
<createTable tableName="REV_HANDBOOK_CHAPTER">
<column name="ID" type="bigint"/>
<column name="REV_ID" type="integer">
<constraints foreignKeyName="FK_REV_HANDBOOK_CHAPTER_REV"
references="REVINFO(REV)"/>
</column>
<column name="HANDBOOK_ID" type="bigint">
<constraints foreignKeyName="FK_REV_HANDBOOK_CHAPTER_HANDBOOK"
references="HANDBOOK(ID)"/>
</column>
<column name="REV_TYPE" type="smallint"/>
</createTable>