I'm using the hibernate3-maven-plugin
to query an Oracle10g database and generate java classes with JPA annotations, using the hbm2java
goal. Then I use spring to configure a session factory that scans the annotated code.
After a long struggle with hbm2java
, I managed to get my classes generated, but now I'm having another issue: I am getting a "Mixing nullable and non nullable columns in a property is not allowed" exception when the annotated classes are loaded.
The database defines tables FOO and BAR as follows:
CREATE TABLE FOO (
STATUS_CODE ... NOT NULL,
REASON_CODE ...);
ALTER TABLE FOO ADD (
CONSTRAINT FK_BAR
FOREIGN KEY (REASON_CODE, STATUS_CODE)
REFERENCES BAR(REASON_CODE, STATUS_CODE));
CREATE TABLE BAR (
STATUS_CODE ... NOT NULL,
REASON_CODE ... NOT NULL);
ALTER TABLE BAR (
PRIMARY KEY (REASON_CODE, STATUS_CODE));
So the table FOO has two columns that are foreign keys into the table BAR. The column FOO.STATUS_CODE must be non-null, but the column FOO.REASON_CODE may be null. The logic here is that a FOO needs a status, but not every status requires a reason.
The table BAR has columns BAR.REASON_CODE and BAR.STATUS_CODE, both of which are non-null. The logic here associates reasons for various (but not all) status codes. So, for example, if the status is 'cancelled' then the reasons may be 'fraud', 'incompetence', etc.
Note that a status such as 'active' does not have any associated reason, and so does not exist in the table BAR, but it can occur as a status code in the table FOO (with no associated reason code). But if a row in FOO has the status code 'cancelled' then it must also have one of the reason codes defined in the table BAR for that status.
So the table definitions seem fine to me (though I am not a database expert).
Now the hbm2java
goal in maven generates the following code for table FOO:
private Bar bar;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumns( {
@JoinColumn(name="REASON_CODE", referencedColumnName="REASON_CODE"),
@JoinColumn(name="STATUS_CODE", referencedColumnName="STATUS_CODE", nullable=false) } )
public Bar getBar() {
return this.bar;
}
Note that only the STATUS_CODE column here is non-nullable.
But when a hibernate session factory bean is created and scans the annotated classes the "Mixing nullable and non nullable columns in a property is not allowed" exception is generated.
Caused by: org.hibernate.AnnotationException: Mixing nullable and non nullable columns in a property is not allowed: com.whatever.domain.LnrPermissionlnrPermStatusReason
at org.hibernate.cfg.Ejb3Column.checkPropertyConsistency(Ejb3Column.java:514)
at org.hibernate.cfg.AnnotationBinder.bindManyToOne(AnnotationBinder.java:2568)
at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1527)
at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:769)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:733)
at org.hibernate.cfg.AnnotationConfiguration.processArtifactsOfType(AnnotationConfiguration.java:636)
Question
Is this a valid error raised by the hibernate annotation processing code (in which case the table definitions in the database need changing), or is it invalid? And if the latter, can I configure the session factory code to ignore such errors?
Configuration
Maven dependencies:
- org.hibernate/hibernate-core/3.5.6-Final
- org.hibernate/hibernate-annotations/3.5.6-Final
- org.springframework/spring-orm/3.1.2-RELEASE
Spring application context:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.whatever.domain" />
</bean>