JPA 2.1 testing: persisting the pre-loaded data

2019-08-25 09:40发布

I'm testing my JPA classes using Arquillian against "remote" containers (Glassfish 4 and WildFly 10, to be specific). I want to:

  • Generate the database schema from the JPA entities' definitions (as opposed to SQL scripts).
  • Pre-load some data to imitate "the data that was already there". For a most trivial example, to test if I can remove an entity without creating it in the same test first.
  • Be able to perform queries, inserts, updates, deletes, etc.

There are javax.persistence.* properties that seem to fit the bill, so one might assume, that the following will work:

<persistence-unit name="test">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>java:/H2DS</jta-data-source>
        <properties>

      <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>

      <property name="javax.persistence.schema-generation.create-source" value="metadata"/>


      <property name="javax.persistence.sql-load-script-source" value="META-INF/sql/load_script.sql"/>

      <property name="javax.persistence.schema-generation.drop-source" value="script"/>
      <property name="javax.persistence.schema-generation.drop-script-source" value="META-INF/sql/drop.sql" />          

</properties>

Well, not quite.

If one uses a GenerationType.TABLE, then one must update the values for the primary key sequences along with inserting new entities using an SQL script. The problem is that though a few entities are inserted using script (the primary key value in "generator-table" is also updated, of course), the JPA provider does not update its preallocated IDs in any way. So, what happens, as much as I can judge from the logs, is:

  • the "generator-table" is created
  • the primary keys 1-5 are pre-allocated (but the value in DB table is not updated
  • Three entries from script are inserted (but, again, this is not committed yet)
  • select and update statements for "generator-table" are prepared (but not executed yet)
  • insert statement for an entity instance from the test is prepared, and a wrong primary key is assigned. "Wrong" is -1 in case of Hibernate, and 1 in case of EclipseLink. The latter throws exception because of duplicate entry, of course.

Solutions found so far

EclipseLink: works, if both DB schema and data pre-loading are done with scripts. Suboptimal for the development stage, as one has to fiddle with SQL scripts often.

Hibernate: works, if the following implementation-specific option is set:

<property name="hibernate.id.new_generator_mappings" value="false"/>

That allows to persist an entity from test, the primary key being 3 times the allocation size (15, with 3 entities).

Now, to the question: is there some "standard JPA", implementation-independent way to achieve my requirements as listed in the beginning of this question? They do not seem extravagant at all, so there should be existing solutions, right?

0条回答
登录 后发表回答