Re: [hibernate-dev] Composite IDs with a null property/field
I've already chimed in ;) I don't think this is something we should do. On Wed, Dec 18, 2019, 3:44 PM Gail Badner wrote: > The main obstacle I see is that Hibernate assumes that ID columns are > non-nullable, even if ID columns are explicitly mapped as nullable. > > This is consistent with the JPA spec, which says: > > "Every entity must have a primary key." > > ANSI SQL 92 says: > > "In addition, if the unique constraint was defined with PRIMARY KEY, then > it requires that none of the values in the specified column or columns be > the null value." > > javax.persistence.Column#nullable has a default of true. > > Since Hibernate ignores the default (as appropriate for a primary key), I > think that it is also appropriate to ignore an explicit mapping to make it > nullable (i.e., @Column(nullable="true")). > > I don't think it's a good idea to add a new property that would change > this behavior for ID columns. > > Aside from the issue I mentioned above about ComponentType#hydrate [1], > SQL Hibernate generates for loading an entity by ID would have to change. > Currently, Hibernate generates SQL like the following: > > select ... from ... where bundle = ? and key = ? and locale = ? > > If the locale column is null, then Session#get will return null. > > It is possible to create a custom (@Loader) to change the query used by > Session#get. > > Unfortunately, that won't work when loading entities with a Query like > "from ... where id = ?". > > IMO, if we want to support this use case, we should use Hibernate-specific > annotations to indicate that a composite ID column should be forced to be > nullable. > > I haven't thought too much about this yet, but something like the > following comes to mind: > > @EnbeddedId > @UniqueKeyIdColumns( uniqueKeyIdColumns = { > @UniqueKeyIdColumn( name="BUNDLE_NAME" ), > @UniqueKeyIdColumn( name="KEY" ), > @UniqueKeyIdColumn( name="LOCALE", nullable="true" ) > } > > The default for UniqueKeyIdColumn#nullable would be false. > > This would likely affect SPIs. > > Honestly, I am on the fence about whether this use case should be > supported. > > Steve, Emmanuel, please chime in with your opinion? > > Thanks, > Gail > > [1] > https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java#L671-L675 > > On Tue, Dec 17, 2019 at 10:41 AM Gail Badner wrote: > >> Jan-Willem, thanks very much for your feedback! >> >> You may be right about Hibernate not allowing a formula for a composite >> ID property. It appears it's not allowed when hbm mapping is used. I'll >> have to check to see if a formula is allowed when mapped with annotations.. >> >> Looking a the mapping for Address again, I see the composite ID does not >> contain a formula. Instead Address is associated with 2 different entity >> names, each with a specified "where" attribute that indicates which entity >> name the specific mapping is for: >> >> >table="Address" >>entity-name="BillingAddress" >>where="add_type='BILLING'" >>check="add_type in ('BILLING', 'SHIPPING')" >>select-before-update="true" >>dynamic-update="true"> >> >> >> >> >> >>... >> >> >> >> >table="Address" >>entity-name="ShippingAddress" >>where="add_type='SHIPPING'" >>select-before-update="true" >>dynamic-update="true"> >> >> >> >> >> >>... >> >> >> We would need to check the entity's "where" attribute or @Where clause >> attribute value to see if the fragment references a composite ID column. >> >> Regards, >> Gail >> >> On Tue, Dec 17, 2019 at 1:29 AM Jan-Willem Gmelig Meyling < >> jan-wil...@youngmediaexperts.nl> wrote: >> >>> PostgreSQL doesn’t allow nullable columns in a compound primary key. It >>> allows a unique constraint on a nullable column, but then it happily >>> inserts the two values below - without constraint violation error. >>> >>> I too have stumbled upon the need for nullable identifiers in Hibernate >>> however. Mostly when I want to map native query results without an actual >>> PK to an entity class. Another use case is mapping a @Subselect entity. >>> These may not have an actual identifier, for example when creating a join >>> product, so in order for all results to appear at all, you specify a >>> compound key based on your requirements. I have experienced that this >>> compound key may contain null values (in case of a LEFT JOIN for example). >>> >>> As far as I am aware, it is currently not allowed to use Formula’s as >>> @Id - I’ve stumbled upon this exception recently and I think correctly so . >>> Maybe it is allowed for compound keys however. I think its safe to only >>> allow null properties in an compound identifier if none of the identifier >>> properties is a formula. >>> >>> Kind regards, >>> >>> Jan-Willem >>> >>> >>> >>> >>> >>> >>> > On 17 Dec 2019, at 00:26, Gail Badner wrote: >>> > >>> > I've confirmed that the same inserts
Re: [hibernate-dev] Composite IDs with a null property/field
The main obstacle I see is that Hibernate assumes that ID columns are non-nullable, even if ID columns are explicitly mapped as nullable. This is consistent with the JPA spec, which says: "Every entity must have a primary key." ANSI SQL 92 says: "In addition, if the unique constraint was defined with PRIMARY KEY, then it requires that none of the values in the specified column or columns be the null value." javax.persistence.Column#nullable has a default of true. Since Hibernate ignores the default (as appropriate for a primary key), I think that it is also appropriate to ignore an explicit mapping to make it nullable (i.e., @Column(nullable="true")). I don't think it's a good idea to add a new property that would change this behavior for ID columns. Aside from the issue I mentioned above about ComponentType#hydrate [1], SQL Hibernate generates for loading an entity by ID would have to change. Currently, Hibernate generates SQL like the following: select ... from ... where bundle = ? and key = ? and locale = ? If the locale column is null, then Session#get will return null. It is possible to create a custom (@Loader) to change the query used by Session#get. Unfortunately, that won't work when loading entities with a Query like "from ... where id = ?". IMO, if we want to support this use case, we should use Hibernate-specific annotations to indicate that a composite ID column should be forced to be nullable. I haven't thought too much about this yet, but something like the following comes to mind: @EnbeddedId @UniqueKeyIdColumns( uniqueKeyIdColumns = { @UniqueKeyIdColumn( name="BUNDLE_NAME" ), @UniqueKeyIdColumn( name="KEY" ), @UniqueKeyIdColumn( name="LOCALE", nullable="true" ) } The default for UniqueKeyIdColumn#nullable would be false. This would likely affect SPIs. Honestly, I am on the fence about whether this use case should be supported. Steve, Emmanuel, please chime in with your opinion? Thanks, Gail [1] https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java#L671-L675 On Tue, Dec 17, 2019 at 10:41 AM Gail Badner wrote: > Jan-Willem, thanks very much for your feedback! > > You may be right about Hibernate not allowing a formula for a composite ID > property. It appears it's not allowed when hbm mapping is used. I'll have > to check to see if a formula is allowed when mapped with annotations.. > > Looking a the mapping for Address again, I see the composite ID does not > contain a formula. Instead Address is associated with 2 different entity > names, each with a specified "where" attribute that indicates which entity > name the specific mapping is for: > > table="Address" >entity-name="BillingAddress" >where="add_type='BILLING'" >check="add_type in ('BILLING', 'SHIPPING')" >select-before-update="true" >dynamic-update="true"> > > > > > >... > > > > table="Address" >entity-name="ShippingAddress" >where="add_type='SHIPPING'" >select-before-update="true" >dynamic-update="true"> > > > > > >... > > > We would need to check the entity's "where" attribute or @Where clause > attribute value to see if the fragment references a composite ID column. > > Regards, > Gail > > On Tue, Dec 17, 2019 at 1:29 AM Jan-Willem Gmelig Meyling < > jan-wil...@youngmediaexperts.nl> wrote: > >> PostgreSQL doesn’t allow nullable columns in a compound primary key. It >> allows a unique constraint on a nullable column, but then it happily >> inserts the two values below - without constraint violation error. >> >> I too have stumbled upon the need for nullable identifiers in Hibernate >> however. Mostly when I want to map native query results without an actual >> PK to an entity class. Another use case is mapping a @Subselect entity. >> These may not have an actual identifier, for example when creating a join >> product, so in order for all results to appear at all, you specify a >> compound key based on your requirements. I have experienced that this >> compound key may contain null values (in case of a LEFT JOIN for example). >> >> As far as I am aware, it is currently not allowed to use Formula’s as @Id >> - I’ve stumbled upon this exception recently and I think correctly so . >> Maybe it is allowed for compound keys however. I think its safe to only >> allow null properties in an compound identifier if none of the identifier >> properties is a formula. >> >> Kind regards, >> >> Jan-Willem >> >> >> >> >> >> >> > On 17 Dec 2019, at 00:26, Gail Badner wrote: >> > >> > I've confirmed that the same inserts result in a constraint violation >> using >> > Oracle 12c: >> > >> > insert into bundle (BUNDLE_NAME, KEY, LOCALE) values('bundle1', 'key1', >> > null); >> > insert into bundle (BUNDLE_NAME, KEY, LOCALE) values('bundle1', 'key1', >> > null); >> > >> > I'm trying to figure out what would be needed to support this. >> >
[hibernate-dev] Google Spanner support for Hibernate ORM
Hi all, Ray Tsang just wrote a nice blog on in.relation.to about the new support for Google Spanner in Hibernate ORM: - https://in.relation.to/2019/12/18/google-cloud-spanner-dialect/ It's Ray's first blog on in.relation.to, you might have heard of him as he presents frequently at events in his role as Developer Advocate at Google Cloud Platform, and a Java Champion too. Also if you don't mind, advertise it on twitter: - https://twitter.com/Hibernate/status/1207321287623954432 Thanks, Sanne ___ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev