r3mbol
r3mbol

Reputation: 261

Can I change default (AUTO) value for GenerationType in @GeneratedValue for persistence unit?

I'm writing junit tests for a server part of our application that connects to a database. Our usual strategy is to put into src/test/resources/ new META-INF/persistence.xml file that overrides the default one so that tests won't connect to Oracle database, but hsqldb.

And here is my problem - one of the entities has a field defined like so:

@Id
@Column(name = "ID", nullable = false)
@SequenceGenerator(name="sequence", sequenceName="sequence")
@GeneratedValue(generator="sequence")
protected Integer id;

During standard run of the application it works fine - I'm not defining specific strategy for @GeneratedValue so it defaults to GenerationType.AUTO which, according to http://docs.oracle.com/javaee/5/api/javax/persistence/GenerationType.html#AUTO , lets the persistence provider decide which strategy to use depending on which database lies underneath, and since normally it's Oracle and Oracle's default generator strategy is GenerationType.SEQUENCE.

But when I run tests I get:

[junit] Testcase: xxx.TestCase took 0 sec
[junit]     Caused an ERROR
[junit] "xxx.Entity.id" declares generator name "sequence", but uses the AUTO generation type.  The only valid generator names under AUTO are "uuid-hex" and "uuid-string".

According to comment in Hibernate @generatedvalue for HSQLDB hsqldb's default strategy is GenerationType.IDENTITY.

The obvious solution would be to add strategy=GenerationType.SEQUENCE to entity's field definition, but 1) it's generally bad practice to change working code to accomodate for test cases 2) I don't exactly have access nor authority to change this entity. So assuming I can't change that my next hunch would be to put some property in our test META-INF/persistence.xml inside persistece-unit definition that would tell Hibernate to default generator strategy to SEQUENCE instead of database's default.

Can I do that, if yes then how can I do that, if no then what else can I do?

Upvotes: 3

Views: 6424

Answers (2)

Mikko Maunu
Mikko Maunu

Reputation: 42094

No, you cannot change default for whole persistence unit but you can override strategy in XML mappings:

@Entity
public class EntityA {
    @Id
    @GeneratedValue
    protected Integer id;
    ...
}

orm.xml in META-INF:

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd" version="2.0">
    <package>somepackage.somewhere</package>
    <entity class="EntityA" metadata-complete="false" access="FIELD">
        <attributes>
            <id name="id">
                <generated-value strategy="SEQUENCE"/>
             </id>
        </attributes>
    </entity>
</entity-mappings>

In above example metadata-complete="false" means that those annotations that are not overridden will still apply. File is pasted as full, because often people have difficulties with copy-paste from multiple sources.

More about overriding mappings can be found for example from Hibernate documentation.

Upvotes: 3

Zaw Than oo
Zaw Than oo

Reputation: 9935

Make sure to do SEQUENCE in the database.

Example :

CREATE SEQUENCE example_sq START WITH 50 INCREMENT BY 50;   

Use strategy=GenerationType.SEQUENCE. Here is more reference.

@Id
@SequenceGenerator(name = "sequence", sequenceName = "sequence", allocationSize=50)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="sequence")
protected Integer id;

Upvotes: 0

Related Questions