Hibernate HBM2DDL produces nullable field for primary foreign key?
I'm using hbm2ddl (from the hibernate3-maven-plugin 2.2) to produce a DDL based on my JPA annotated entities. Normally, this works fine but I recently introduced an entity that uses a composite key made up of two foreign keys and this is causing a problem with the DDL generation.
Specifically, the DDL that is generated specifies that the primary key columns are nullable and this should not be the case for primary key columns. As a result, MSSQL fails to create the primary key constraints due to the column being nullable.
Here is the Entity
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@IdClass(PricePK.class)
public class Price extends PersistentEntity {
@Id
@ManyToOne(optional = false)
private Product product;
@Id
@ManyToOne(optional = false)
private Currency currency;
@Column(nullable = false)
private BigDecimal amount;
...etc...
}
The entity specifies that it uses PricePK as its primary key class and, more importantly, that the two ManyToOne entities which make up the primary key are not optional (which should mean the columns are 'not null' in the DDL). Here is the PricePK class:
@Embeddable
public class 开发者_如何学PythonPricePK implements Serializable {
Integer product;
Integer currency;
...etc...
}
The DDL that is produced for the Price table is as follows - note that currency_id and product_id both allow null:
create table PRICE (
version int null,
amount numeric(19,2) not null,
currency_id int null,
product_id int null,
primary key (currency_id, product_id)
);
When i try to run the script in MSSql I get the following (not surprising) error:
Unsuccessful: create table store.PRICE (version int null, amount numeric(19,2) null, currency_id int null, product_id int null, primary key (currency_id, product_id)) Cannot define PRIMARY KEY constraint on nullable column in table 'PRICE'.
Any idea why the DDL that is being produced specifies 'null' for these two foreign key columns?
You probably can work-around the problem by using some variant of @Column(nullable = false) on the fields/getters of PricePK.
I can see a couple of things not quite right with your mapping:
- No need of
@Embeddable
with@IdClass
- The key should refer to the entities not the entities id
When I change the mapping to:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@IdClass(PricePK.class)
public class Price {
@Id
@ManyToOne(optional = false)
Product product;
@Id
@ManyToOne(optional = false)
Currency currency;
@Column(nullable = false)
BigDecimal amount;
}
public class PricePK implements Serializable {
Product product;
Currency currency;
@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
PricePK pricePK = (PricePK) o;
return Objects.equals( product, pricePK.product ) && Objects.equals(
currency,
pricePK.currency
);
}
These are the queries used to create the tables:
create table Price (
amount numeric(19,2) not null,
product_id numeric(19,0) not null,
currency_id numeric(19,0) not null,
primary key (currency_id, product_id)
)
alter table Price
add constraint FKbd5rb0nj1jehdn4x7fu01rk7n
foreign key (product_id)
references Product
alter table Price
add constraint FKb5kubh6h82dbyovrtcuby54d2
foreign key (currency_id)
references Currency
I've tested this with Hibernate ORM 5.5.0.Final and dialect org.hibernate.dialect.SQLServerDialect
精彩评论