Skip to content

Commit 8fd64a3

Browse files
committed
HHH-9807 - Better error message when @formula and @id are combined
1 parent 05d697b commit 8fd64a3

File tree

4 files changed

+56
-6
lines changed

4 files changed

+56
-6
lines changed

hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.util.HashSet;
1717
import java.util.Iterator;
1818
import java.util.List;
19+
import java.util.Locale;
1920
import java.util.Map;
2021
import java.util.Properties;
2122
import java.util.Set;
@@ -135,6 +136,7 @@
135136
import org.hibernate.boot.spi.MetadataBuildingContext;
136137
import org.hibernate.cfg.annotations.CollectionBinder;
137138
import org.hibernate.cfg.annotations.EntityBinder;
139+
import org.hibernate.cfg.annotations.HCANNHelper;
138140
import org.hibernate.cfg.annotations.MapKeyColumnDelegator;
139141
import org.hibernate.cfg.annotations.MapKeyJoinColumnDelegator;
140142
import org.hibernate.cfg.annotations.Nullability;
@@ -145,7 +147,6 @@
145147
import org.hibernate.engine.OptimisticLockStyle;
146148
import org.hibernate.engine.spi.FilterDefinition;
147149
import org.hibernate.id.PersistentIdentifierGenerator;
148-
import org.hibernate.internal.CoreLogging;
149150
import org.hibernate.internal.CoreMessageLogger;
150151
import org.hibernate.internal.util.StringHelper;
151152
import org.hibernate.loader.PropertyPath;
@@ -2191,6 +2192,16 @@ else if ( !isId || !entityBinder.isIgnoreIdAnnotations() ) {
21912192
if ( isId || ( !optional && nullability != Nullability.FORCED_NULL ) ) {
21922193
//force columns to not null
21932194
for ( Ejb3Column col : columns ) {
2195+
if ( isId && col.isFormula() ) {
2196+
throw new CannotForceNonNullableException(
2197+
String.format(
2198+
Locale.ROOT,
2199+
"Identifier property [%s] cannot contain formula mapping [%s]",
2200+
HCANNHelper.annotatedElementSignature( property ),
2201+
col.getFormulaString()
2202+
)
2203+
);
2204+
}
21942205
col.forceNotNull();
21952206
}
21962207
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.cfg;
8+
9+
import org.hibernate.AnnotationException;
10+
import org.hibernate.HibernateException;
11+
12+
/**
13+
* Indicates an internal attempt to mark a column as non-nullable (because its part
14+
* of a PK, etc) but we cannot force that column to be non-nullable.
15+
* <p/>
16+
* Typically this indicates that the "column" is actually a formula.
17+
*
18+
* @author Steve Ebersole
19+
*/
20+
public class CannotForceNonNullableException extends AnnotationException {
21+
public CannotForceNonNullableException(String message) {
22+
super( message );
23+
}
24+
}

hibernate-core/src/main/java/org/hibernate/cfg/Ejb3Column.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,12 @@ public Join getJoin() {
457457
}
458458

459459
public void forceNotNull() {
460+
if ( mappingColumn == null ) {
461+
throw new CannotForceNonNullableException(
462+
"Cannot perform #forceNotNull because internal org.hibernate.mapping.Column reference is null: " +
463+
"likely a formula"
464+
);
465+
}
460466
mappingColumn.setNullable( false );
461467
}
462468

hibernate-core/src/test/java/org/hibernate/test/annotations/id/AndFormulaTest.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,17 @@
1313
import org.hibernate.boot.MetadataSources;
1414
import org.hibernate.boot.registry.StandardServiceRegistry;
1515
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
16+
import org.hibernate.cfg.CannotForceNonNullableException;
1617

17-
import org.hibernate.testing.FailureExpected;
1818
import org.hibernate.testing.junit4.BaseUnitTestCase;
1919
import org.junit.AfterClass;
2020
import org.junit.BeforeClass;
2121
import org.junit.Test;
2222

23+
import static org.hamcrest.CoreMatchers.startsWith;
24+
import static org.junit.Assert.assertThat;
25+
import static org.junit.Assert.fail;
26+
2327
/**
2428
* Originally developed for HHH-9807 - better error message on combination of {@code @Id} + {@code @Formula}
2529
*
@@ -41,11 +45,16 @@ public static void releaseServiceRegistry() {
4145
}
4246

4347
@Test
44-
@FailureExpected( jiraKey = "HHH-9807" )
4548
public void testBindingEntityWithIdAndFormula() {
46-
new MetadataSources( ssr )
47-
.addAnnotatedClass( EntityWithIdAndFormula.class )
48-
.buildMetadata();
49+
try {
50+
new MetadataSources( ssr )
51+
.addAnnotatedClass( EntityWithIdAndFormula.class )
52+
.buildMetadata();
53+
fail( "Expecting failure from invalid mapping" );
54+
}
55+
catch (CannotForceNonNullableException e) {
56+
assertThat( e.getMessage(), startsWith( "Identifier property [" ) );
57+
}
4958
}
5059

5160
@Entity

0 commit comments

Comments
 (0)