4

I'm trying to use JPA with Hibernate to read data from an existing schema. I cannot modify the schema. There is a User class with multiple subclasses. Some of these subclasses have additional data that is stored in joined tables, and some don't. As a concrete example, consider the following 3 classes and 2 tables. (In reality, there are a couple dozen variants and about a dozen tables.)

  • User is the common base class. It includes a discriminator column named userType. The table USER holds the data common to all User classes, including a numeric USERID value.
  • StandardUser is one variant with no additional data.
  • LoginUser is another variant that has a username and password, stored in a table LOGIN_USER that is joined to USER on USERID.

The following works with OpenJPA:

@Entity
@Table(name="USER")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="USERTYPEID", discriminatorType=DiscriminatorType.INTEGER)
public class User {
    private @Id long userId;
    private String userName;
    private int userTypeId;
    ...
}

@Entity
@Table(name="USER")
@DiscriminatorValue("1")
public class StandardUser extends User {

}

@Entity
@Table(name="LOGIN_USER")
@DiscriminatorValue("2")
public class LoginUser extends User {
    private String login;
    private String password;
    ....
}

It generates SQL code that joins USER and LOGIN_USER (with a left outer join) on USERID, and properly creates a StandardUser or a LoginUser depending on whether the userTypeId value is 1 or 2.

When I link the same code with Hibernate instead of OpenJPA, I get the error message

Caused by: org.hibernate.AnnotationException: Foreign key circularity dependency involving the following tables: 

There are no tables listed in the error message. I set a breakpoint on the exception, and it is trying to resolve the "dependency" between "USER" and "USER", or so it appears. I have tried this with Hibernate versions 3.6 and 4.1.7.

(Why not stick with OpenJPA? I am having a separate problem there, relating to load time code rewriting conflicts with JAXB.)

Spencer
  • 473
  • 6
  • 13

1 Answers1

1

I should have spent more time looking at the related questions. It appears that the strategy proposed in Changing the inheritance strategy in branches of the class hierarchy via JPA annotations will do what I need.

Specifically, if I change the code to read as follows, it compiles and runs and passes my unit tests.

@Entity
@Table(name="USER")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="USERTYPEID", discriminatorType=DiscriminatorType.INTEGER)
@DiscriminatorValue("1")
public class User {
    private @Id long userId;
    private String userName;
    private int userTypeId;
    ...
}

@Entity
@DiscriminatorValue("1")
public class StandardUser {
}

@Entity
@SecondaryTable(name="LOGIN_USER")
@DiscriminatorValue("2")
public class LoginUser extends User {
    @Column(table="LOGIN_USER")
    private String login;
    @Column(table="LOGIN_USER")
    private String password;
    ....
}
Community
  • 1
  • 1
Spencer
  • 473
  • 6
  • 13
  • Does this still work for you? I have a similar problem and in my case I get the equivalent of: `javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [standard_user]` – Scott Plante May 09 '22 at 18:17