You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Lennart Jörelid <le...@gmail.com> on 2011/04/05 10:17:55 UTC

OpenJPA Sequence Generation in HSQLDB broken?

Hello there,

I am trying to make automated JPA integration tests using OpenJPA and HSQLDB.
The entities use automated IDs generated with Database Sequences, as shown in the entity code snippets below.
However, I encounter strange behavior when running unit tests - the OpenJPA-generated Sequence seems 
not generated within HSQLDB, despite log messages indicating the opposite. 
I have run the unit tests on both OpenJPA 1.2.X and 2.0.X, with identical results:

<openjpa-1.2.2-r422266:898935 fatal store error> org.apache.openjpa.persistence.RollbackException: 
Sequence not found: DEBUGTINDRAENTITYSEQ in statement 
[SELECT NEXT VALUE FOR DebugTindraEntitySeq FROM INFORMATION_SCHEMA.SYSTEM_SEQUENCES] 
{SELECT NEXT VALUE FOR DebugTindraEntitySeq FROM INFORMATION_SCHEMA.SYSTEM_SEQUENCES} 
[code=-191, state=S0002]

This seems to be caused by the sequences not being created, although the OpenJPA log claims:
"executing stmnt 547527790 CREATE SEQUENCE DebugTindraEntitySeq START WITH 1"

However, firing the query 

String query = "SELECT * FROM INFORMATION_SCHEMA.SYSTEM_SEQUENCES";
Query q = unitTestEM.createNativeQuery(query);
List result = q.getResultList();
log.info("Got [" + result.size() + "] sequences");

I get the log printout: 	Got [0] sequences

The same behavior is seen in the H2 database. 
What should be done in OpenJPA to make the sequences actually being created within the HSQLDB?
Any other suggestions to create working automated JUnit tests using OpenJPA?


============ Code snippet #1: Entity class ============ 


@SequenceGenerator(name = DebugTindraEntity.SEQ, sequenceName = DebugTindraEntity.SEQ, allocationSize = 1)
@Entity
public class DebugTindraEntity extends TindraEntity {

    // Constants
    private static final long serialVersionUID = 8829990017L;
    public static final String SEQ = "DebugTindraEntitySeq";
    
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SEQ)
    @XmlElement(nillable = true, required = false)
    private int id;

    @Basic
    @Column(nullable = false)
    private String name;

    ....

============ Code snippet #2: Mapped superclass ============ 

The TindraEntity mapped superclass holds the JPA version field. I would have loved to place 

@MappedSuperclass
public abstract class TindraEntity implements Serializable {

    // Internal state
    private static final long serialVersionUID = 8829990001L;

    // Internal state
    @Version
    @XmlElement(nillable = true, required = false)
    private int version;

    ....

============ Code snippet #2: Persistence.xml file ============ 

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
             version="1.0">

    <persistence-unit name="InjectedInmemoryPU" transaction-type="RESOURCE_LOCAL">

        <description>
            PersistenceUnit containing the Entity classes.
        </description>
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>

        <class>com.teliasonera.tindra.core.common.persistence.TindraEntity</class>
        <class>com.teliasonera.tindra.core.common.persistence.DebugTindraEntity</class>

        <!--
            When set to true then only listed classes and jars will
            be scanned for persistent classes, otherwise the enclosing
            jar or directory will also be scanned. Not applicable to
            Java SE persistence units.
        -->
        <exclude-unlisted-classes>false</exclude-unlisted-classes>

        <properties>
            <property name="openjpa.jdbc.DBDictionary" value="hsql(SimulateLocking=true, SchemaCase=upper)"/>
            <property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver" />
            <property name="openjpa.ConnectionURL"  value="jdbc:hsqldb:mem:unittestDatabaseID;shutdown=true"/>

            <property name="openjpa.ConnectionUserName" value="sa"/>
            <property name="openjpa.ConnectionPassword" value=""/>
            <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
            <property name="openjpa.InverseManager" value="true"/>
            <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO, SQL=TRACE"/>
            <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>
        </properties>

    </persistence-unit>
</persistence>

--
// Bästa hälsningar, 
// [sw. "Best regards,"]
//
// Lennart Jörelid

Re: OpenJPA Sequence Generation in HSQLDB broken?

Posted by Miłosz Tylenda <mt...@o2.pl>.
Hi Lennart,

You are using an in-memory database and "shutdown=true" in the URL. This causes the database be shut down when the last connection terminates. I guess that what's happening here is the sequence is created, then the connection terminates and when a new connection starts you are in fact in a new and clean database without any objects. Try dropping the "shutdown=true" from the URL. You might also experiment with a connection pool which could keep a connection open throughout the test.

For the H2 database, use this syntax: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1.

Greetings,
Milosz


> Hello there,
> 
> I am trying to make automated JPA integration tests using OpenJPA and HSQLDB.
> The entities use automated IDs generated with Database Sequences, as shown in the entity code snippets below.
> However, I encounter strange behavior when running unit tests - the OpenJPA-generated Sequence seems 
> not generated within HSQLDB, despite log messages indicating the opposite. 
> I have run the unit tests on both OpenJPA 1.2.X and 2.0.X, with identical results:
> 
> <openjpa-1.2.2-r422266:898935 fatal store error> org.apache.openjpa.persistence.RollbackException: 
> Sequence not found: DEBUGTINDRAENTITYSEQ in statement 
> [SELECT NEXT VALUE FOR DebugTindraEntitySeq FROM INFORMATION_SCHEMA.SYSTEM_SEQUENCES] 
> {SELECT NEXT VALUE FOR DebugTindraEntitySeq FROM INFORMATION_SCHEMA.SYSTEM_SEQUENCES} 
> [code=-191, state=S0002]
> 
> This seems to be caused by the sequences not being created, although the OpenJPA log claims:
> "executing stmnt 547527790 CREATE SEQUENCE DebugTindraEntitySeq START WITH 1"
> 
> However, firing the query 
> 
> String query = "SELECT * FROM INFORMATION_SCHEMA.SYSTEM_SEQUENCES";
> Query q = unitTestEM.createNativeQuery(query);
> List result = q.getResultList();
> log.info("Got [" + result.size() + "] sequences");
> 
> I get the log printout: 	Got [0] sequences
> 
> The same behavior is seen in the H2 database. 
> What should be done in OpenJPA to make the sequences actually being created within the HSQLDB?
> Any other suggestions to create working automated JUnit tests using OpenJPA?
> 
> 
> ============ Code snippet #1: Entity class ============ 
> 
> 
> @SequenceGenerator(name = DebugTindraEntity.SEQ, sequenceName = DebugTindraEntity.SEQ, allocationSize = 1)
> @Entity
> public class DebugTindraEntity extends TindraEntity {
> 
>     // Constants
>     private static final long serialVersionUID = 8829990017L;
>     public static final String SEQ = "DebugTindraEntitySeq";
>     
>     @Id
>     @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SEQ)
>     @XmlElement(nillable = true, required = false)
>     private int id;
> 
>     @Basic
>     @Column(nullable = false)
>     private String name;
> 
>     ....
> 
> ============ Code snippet #2: Mapped superclass ============ 
> 
> The TindraEntity mapped superclass holds the JPA version field. I would have loved to place 
> 
> @MappedSuperclass
> public abstract class TindraEntity implements Serializable {
> 
>     // Internal state
>     private static final long serialVersionUID = 8829990001L;
> 
>     // Internal state
>     @Version
>     @XmlElement(nillable = true, required = false)
>     private int version;
> 
>     ....
> 
> ============ Code snippet #2: Persistence.xml file ============ 
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <persistence xmlns="http://java.sun.com/xml/ns/persistence"
>              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>              xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
>              version="1.0">
> 
>     <persistence-unit name="InjectedInmemoryPU" transaction-type="RESOURCE_LOCAL">
> 
>         <description>
>             PersistenceUnit containing the Entity classes.
>         </description>
>         <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
> 
>         <class>com.teliasonera.tindra.core.common.persistence.TindraEntity</class>
>         <class>com.teliasonera.tindra.core.common.persistence.DebugTindraEntity</class>
> 
>         <!--
>             When set to true then only listed classes and jars will
>             be scanned for persistent classes, otherwise the enclosing
>             jar or directory will also be scanned. Not applicable to
>             Java SE persistence units.
>         -->
>         <exclude-unlisted-classes>false</exclude-unlisted-classes>
> 
>         <properties>
>             <property name="openjpa.jdbc.DBDictionary" value="hsql(SimulateLocking=true, SchemaCase=upper)"/>
>             <property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver" />
>             <property name="openjpa.ConnectionURL"  value="jdbc:hsqldb:mem:unittestDatabaseID;shutdown=true"/>
> 
>             <property name="openjpa.ConnectionUserName" value="sa"/>
>             <property name="openjpa.ConnectionPassword" value=""/>
>             <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
>             <property name="openjpa.InverseManager" value="true"/>
>             <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO, SQL=TRACE"/>
>             <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>
>         </properties>
> 
>     </persistence-unit>
> </persistence>
> 
> --
> // Bästa hälsningar, 
> // [sw. "Best regards,"]
> //
> // Lennart Jörelid
>