Note that there are some explanatory texts on larger screens.

plurals
  1. POOverride Hibernate Annotations
    primarykey
    data
    text
    <p>I am developing a Java Application that uses Hibernate and is connected to an Oracle instance. Another client is looking to use the same application, but requires it run on MS SQL Server. I would like to avoid making changes to the existing annotations and instead create a package of xml files that we can drop in depending on the environment.</p> <p>One way to do this is using JPA XML configuration to override the existing class annotations. However, JPA does not support generic generators, which is a requirement due to the structure of our legacy database. The other way that I am looking into is to use Hibernate XML configs to remap entire classes and have access to the <code>generator</code> xml tag. This solution has some issues though: </p> <ul> <li>Hibernate does not allow you to selectively override entity members</li> <li>Hibernate does not allow you to re-map the same class (e.g. <code>org.hibernate.AnnotationException: Use of the same entity name twice</code>)</li> </ul> <p>Does anyone have any experience with overriding annotations using Hibernate XML Configuration files or is JPA the only way to go?</p> <h3>Update with an Example</h3> <p>In Oracle, Sequences are used to generate unique IDs when inserting new records into the database. An id would then be annotated in the following manner:</p> <pre><code>@Id @GeneratedValue(generator="EXAMPLE_ID_GEN", strategy=GenerationType.SEQUENCE) @SequenceGenerator(name="EXAMPLE_ID_GEN", sequenceName="SEQ_EXAMPLE_ID") @Column(name = "EXAMPLE_ID") public String getExampleId() { return this.exampleId; } </code></pre> <p>However, MS SQL Server does not have the concept of Sequences (Ideological differences). Therefore, you could use a table generator to simulate sequences. </p> <pre><code>@Id @GeneratedValue(generator="EXAMPLE_ID_GEN", strategy=GenerationType.TABLE) @TableGenerator(name="EXAMPLE_ID_GEN", tableName="SEQUENCE", valueColumnName="VALUE", pkColumnName="SEQUENCE", pkColumnValue="EXAMPLE_ID") public String getExampleId() { return this.exampleId; } </code></pre> <p>Two different configurations for two different types of databases. Keep in mind that this is a legacy database and that we aren't going to rewrite our application to support SQL Server identities, the native id generator for SQL Server (which would also require a different annotation).</p> <p>To alleviate this, I have looked into using Hibernate's <code>@GenericGenerator</code> and point it to a class of my own creation that models <code>org.hibernate.id.SequenceGenerator</code> (or something similar) and also customize the structure of the table by extending <code>org.hibernate.id.TableStructure</code>. </p> <p>Back to my original question - is any of this possible with an XML override?</p> <h3>How I Solved this Problem</h3> <p>So, in the end, I found that JPA and Hibernate did not provide the out-of-box functionality that I was looking for. Instead, I created a custom generator that checked the database dialect and set the TableStructure appropriately. As I explored all options, I ended up using Hibernate's <code>@GenericGenerator</code> annotation. This is an example of the Id generation annotation:</p> <pre><code>@Id @GeneratedValue(generator="EXAMPLE_ID_GEN") @GenericGenerator(name = "EXAMPLE_ID_GEN", strategy="com.my.package.CustomIdGenerator", parameters = { @Parameter(name = "parameter_name", value="parameter_value") }) public String getExampleId() { return this.exampleId; } </code></pre> <p>This solution necessitates that each Hibernate entity be modified with the new Id generator.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload