Search code examples
jpaeclipselink

JPA EclipseLink table creation order


I have a working project that uses JPA to persist data on MySQL (EclipseLink as provider). Recently I wanted to drop the database and create it again with the tables via Eclipse => EclipseLink 'Generate tables from entities'. I also have the persistence.xml updated (first generated automatically, then modified manually to narrow down on this problem).

<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>xxx.entity.options.Difficulty</class>
<class>xxx.entity.options.Options</class>

(Omitted the rest since it is ok otherwise => it is working in general)

The problem is that when I generate the tables I get the error:

Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'xxx.DIFFICULTY' doesn't exist
Error Code: 1146

(The entity classes have table names defined: @Entity @Table(name = "DIFFICULTY"))

If I comment out the 'Options' from persistence.xml, the 'DIFFICULTY' table gets created ok. Then uncommenting 'Options' again and re-generating the tables => the 'OPTIONS' table will be created also (Options has @ManyToOne association with the Difficulty).

In the persistence.xml I have

<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />

as I am still developing.

In the Options class I have

@ManyToOne(optional = false, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
private Difficulty difficulty = null;

(Many Options are suppose to have the same Difficulty selected, so none really owns one. I hope this is correct?)

After The Difficulty and Options tables were created successfully, I was able to re-create the rest of the database tables.

  1. The question is that should I (be able to) specify the order in which the tables are created?
  2. Have I something wrong with the @ManyToOne association?

Already spent couple of hours on this issue, but couldn't figure it out what is the problem.

Sorry for the long text, I just try to explain the whole situation. Last time I received 'tl; dr;' answer (didn't know by that time what it meant), I spent 6 hours looking the wrong thing, so please do not bother to answer in such case.


Solution

  • If you look at the exceptions stack, you'll see it is coming from your entity's default constructor. This constructor is trying to issue a query by obtaining an entitymanager, and is failing because the table it needs doesn't exist yet. When you create that one table, the constructor can query it, which allows everything to proceed.

    You should not have business logic in your default constructor. This is used by the provider, and is getting called during deployment before DDL. Removing that will resolve the issue.