Skip to content

Commit b46395c

Browse files
committed
introduce the @DialectOverride annotation
for overriding certain mapping annotations that specify native SQL
1 parent a05f167 commit b46395c

File tree

7 files changed

+393
-34
lines changed

7 files changed

+393
-34
lines changed
Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
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.annotations;
8+
9+
import org.hibernate.Incubating;
10+
import org.hibernate.dialect.Dialect;
11+
12+
import java.lang.annotation.Annotation;
13+
import java.lang.annotation.Repeatable;
14+
import java.lang.annotation.Retention;
15+
import java.lang.annotation.Target;
16+
17+
import static java.lang.Integer.MAX_VALUE;
18+
import static java.lang.Integer.MIN_VALUE;
19+
import static java.lang.annotation.ElementType.*;
20+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
21+
22+
/**
23+
* Allows certain annotations to be overridden in a given SQL {@link Dialect}.
24+
*
25+
* @author Gavin King
26+
*/
27+
@Incubating
28+
public interface DialectOverride {
29+
30+
/**
31+
* Identifies a database version.
32+
*
33+
* @see org.hibernate.dialect.DatabaseVersion
34+
*/
35+
@Retention(RUNTIME)
36+
@interface Version {
37+
int major();
38+
int minor() default 0;
39+
}
40+
41+
/**
42+
* Specializes a {@link org.hibernate.annotations.Check}
43+
* in a certain dialect.
44+
*/
45+
@Target({METHOD, FIELD, TYPE})
46+
@Retention(RUNTIME)
47+
@Repeatable(Checks.class)
48+
@OverridesAnnotation(org.hibernate.annotations.Check.class)
49+
@interface Check {
50+
/**
51+
* The {@link Dialect} in which this override applies.
52+
*/
53+
Class<? extends Dialect> dialect();
54+
Version before() default @Version(major = MAX_VALUE);
55+
Version sameOrAfter() default @Version(major = MIN_VALUE);
56+
57+
org.hibernate.annotations.Check override();
58+
}
59+
@Target({METHOD, FIELD, TYPE})
60+
@Retention(RUNTIME)
61+
@interface Checks {
62+
Check[] value();
63+
}
64+
65+
/**
66+
* Specializes an {@link org.hibernate.annotations.OrderBy}
67+
* in a certain dialect.
68+
*/
69+
@Target({METHOD, FIELD})
70+
@Retention(RUNTIME)
71+
@Repeatable(OrderBys.class)
72+
@OverridesAnnotation(org.hibernate.annotations.OrderBy.class)
73+
@interface OrderBy {
74+
/**
75+
* The {@link Dialect} in which this override applies.
76+
*/
77+
Class<? extends Dialect> dialect();
78+
Version before() default @Version(major = MAX_VALUE);
79+
Version sameOrAfter() default @Version(major = MIN_VALUE);
80+
81+
org.hibernate.annotations.OrderBy override();
82+
}
83+
@Target({METHOD, FIELD})
84+
@Retention(RUNTIME)
85+
@interface OrderBys {
86+
OrderBy[] value();
87+
}
88+
89+
/**
90+
* Specializes a {@link org.hibernate.annotations.ColumnDefault}
91+
* in a certain dialect.
92+
*/
93+
@Target({METHOD, FIELD})
94+
@Retention(RUNTIME)
95+
@Repeatable(ColumnDefaults.class)
96+
@OverridesAnnotation(org.hibernate.annotations.ColumnDefault.class)
97+
@interface ColumnDefault {
98+
/**
99+
* The {@link Dialect} in which this override applies.
100+
*/
101+
Class<? extends Dialect> dialect();
102+
Version before() default @Version(major = MAX_VALUE);
103+
Version sameOrAfter() default @Version(major = MIN_VALUE);
104+
105+
org.hibernate.annotations.ColumnDefault override();
106+
}
107+
@Target({METHOD, FIELD})
108+
@Retention(RUNTIME)
109+
@interface ColumnDefaults {
110+
ColumnDefault[] value();
111+
}
112+
113+
/**
114+
* Specializes a {@link org.hibernate.annotations.GeneratedColumn}
115+
* in a certain dialect.
116+
*/
117+
@Target({METHOD, FIELD})
118+
@Retention(RUNTIME)
119+
@Repeatable(GeneratedColumns.class)
120+
@OverridesAnnotation(org.hibernate.annotations.GeneratedColumn.class)
121+
@interface GeneratedColumn {
122+
/**
123+
* The {@link Dialect} in which this override applies.
124+
*/
125+
Class<? extends Dialect> dialect();
126+
Version before() default @Version(major = MAX_VALUE);
127+
Version sameOrAfter() default @Version(major = MIN_VALUE);
128+
129+
org.hibernate.annotations.GeneratedColumn override();
130+
}
131+
@Target({METHOD, FIELD})
132+
@Retention(RUNTIME)
133+
@interface GeneratedColumns {
134+
GeneratedColumn[] value();
135+
}
136+
137+
/**
138+
* Specializes a {@link org.hibernate.annotations.DiscriminatorFormula}
139+
* in a certain dialect.
140+
*/
141+
@Target(TYPE)
142+
@Retention(RUNTIME)
143+
@Repeatable(DiscriminatorFormulas.class)
144+
@OverridesAnnotation(org.hibernate.annotations.DiscriminatorFormula.class)
145+
@interface DiscriminatorFormula {
146+
/**
147+
* The {@link Dialect} in which this override applies.
148+
*/
149+
Class<? extends Dialect> dialect();
150+
Version before() default @Version(major = MAX_VALUE);
151+
Version sameOrAfter() default @Version(major = MIN_VALUE);
152+
153+
org.hibernate.annotations.DiscriminatorFormula override();
154+
}
155+
@Target(TYPE)
156+
@Retention(RUNTIME)
157+
@interface DiscriminatorFormulas {
158+
DiscriminatorFormula[] value();
159+
}
160+
161+
/**
162+
* Specializes a {@link org.hibernate.annotations.Formula}
163+
* in a certain dialect.
164+
*/
165+
@Target({METHOD, FIELD})
166+
@Retention(RUNTIME)
167+
@Repeatable(Formulas.class)
168+
@OverridesAnnotation(org.hibernate.annotations.Formula.class)
169+
@interface Formula {
170+
/**
171+
* The {@link Dialect} in which this override applies.
172+
*/
173+
Class<? extends Dialect> dialect();
174+
Version before() default @Version(major = MAX_VALUE);
175+
Version sameOrAfter() default @Version(major = MIN_VALUE);
176+
177+
org.hibernate.annotations.Formula override();
178+
}
179+
@Target({METHOD, FIELD})
180+
@Retention(RUNTIME)
181+
@interface Formulas {
182+
Formula[] value();
183+
}
184+
185+
/**
186+
* Specializes a {@link org.hibernate.annotations.JoinFormula}
187+
* in a certain dialect.
188+
*/
189+
@Target({METHOD, FIELD})
190+
@Retention(RUNTIME)
191+
@OverridesAnnotation(org.hibernate.annotations.JoinFormula.class)
192+
@interface JoinFormula {
193+
/**
194+
* The {@link Dialect} in which this override applies.
195+
*/
196+
Class<? extends Dialect> dialect();
197+
Version before() default @Version(major = MAX_VALUE);
198+
Version sameOrAfter() default @Version(major = MIN_VALUE);
199+
200+
org.hibernate.annotations.JoinFormula override();
201+
}
202+
@Target({METHOD, FIELD})
203+
@Retention(RUNTIME)
204+
@interface JoinFormulas {
205+
JoinFormula[] value();
206+
}
207+
208+
/**
209+
* Specializes a {@link org.hibernate.annotations.Where}
210+
* in a certain dialect.
211+
*/
212+
@Target({METHOD, FIELD, TYPE})
213+
@Retention(RUNTIME)
214+
@OverridesAnnotation(org.hibernate.annotations.Where.class)
215+
@interface Where {
216+
/**
217+
* The {@link Dialect} in which this override applies.
218+
*/
219+
Class<? extends Dialect> dialect();
220+
Version before() default @Version(major = MAX_VALUE);
221+
Version sameOrAfter() default @Version(major = MIN_VALUE);
222+
223+
org.hibernate.annotations.Where override();
224+
}
225+
@Target({METHOD, FIELD, TYPE})
226+
@Retention(RUNTIME)
227+
@interface Wheres {
228+
Where[] value();
229+
}
230+
231+
/**
232+
* Specializes {@link org.hibernate.annotations.Filters}
233+
* in a certain dialect.
234+
*/
235+
@Target({METHOD, FIELD, TYPE})
236+
@Retention(RUNTIME)
237+
@Repeatable(FilterOverrides.class)
238+
@OverridesAnnotation(org.hibernate.annotations.Filters.class)
239+
@interface Filters {
240+
/**
241+
* The {@link Dialect} in which this override applies.
242+
*/
243+
Class<? extends Dialect> dialect();
244+
Version before() default @Version(major = MAX_VALUE);
245+
Version sameOrAfter() default @Version(major = MIN_VALUE);
246+
247+
org.hibernate.annotations.Filters override();
248+
}
249+
@Target({METHOD, FIELD, TYPE})
250+
@Retention(RUNTIME)
251+
@interface FilterOverrides {
252+
Filters[] value();
253+
}
254+
255+
/**
256+
* Specializes {@link org.hibernate.annotations.FilterDefs}
257+
* in a certain dialect.
258+
*/
259+
@Target({PACKAGE, TYPE})
260+
@Retention(RUNTIME)
261+
@Repeatable(FilterDefOverrides.class)
262+
@OverridesAnnotation(org.hibernate.annotations.FilterDefs.class)
263+
@interface FilterDefs {
264+
/**
265+
* The {@link Dialect} in which this override applies.
266+
*/
267+
Class<? extends Dialect> dialect();
268+
Version before() default @Version(major = MAX_VALUE);
269+
Version sameOrAfter() default @Version(major = MIN_VALUE);
270+
271+
org.hibernate.annotations.FilterDefs override();
272+
}
273+
@Target({PACKAGE, TYPE})
274+
@Retention(RUNTIME)
275+
@interface FilterDefOverrides {
276+
FilterDefs[] value();
277+
}
278+
279+
/**
280+
* Marks an annotation type as a dialect-specific override for
281+
* some other annotation type.
282+
* <p>
283+
* The marked annotation must have the following members:
284+
* <ul>
285+
* <li>{@code Class<? extends Dialect> dialect()},
286+
* <li>{@code Version before()},
287+
* <li>{@code Version sameOrAfter()}, and
288+
* <li>{@code A override()}, where {@code A} is the type
289+
* of annotation which the marked annotation overrides.
290+
* </ul>
291+
*/
292+
@Target({ANNOTATION_TYPE})
293+
@Retention(RUNTIME)
294+
@interface OverridesAnnotation {
295+
/**
296+
* The class of the annotation that is overridden.
297+
*/
298+
Class<? extends Annotation> value();
299+
}
300+
}

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737

3838
import org.jboss.logging.Logger;
3939

40+
import static org.hibernate.cfg.AnnotationBinder.getOverridableAnnotation;
41+
4042
/**
4143
* Wrap state of an EJB3 @Column annotation
4244
* and build the Hibernate column mapping element
@@ -672,7 +674,7 @@ public static AnnotatedColumn[] buildColumnFromAnnotation(
672674
private void applyColumnDefault(PropertyData inferredData, int length) {
673675
final XProperty xProperty = inferredData.getProperty();
674676
if ( xProperty != null ) {
675-
ColumnDefault columnDefaultAnn = xProperty.getAnnotation( ColumnDefault.class );
677+
ColumnDefault columnDefaultAnn = getOverridableAnnotation( xProperty, ColumnDefault.class, context );
676678
if ( columnDefaultAnn != null ) {
677679
if (length!=1) {
678680
throw new MappingException("@ColumnDefault may only be applied to single-column mappings");
@@ -690,7 +692,7 @@ private void applyColumnDefault(PropertyData inferredData, int length) {
690692
private void applyGeneratedAs(PropertyData inferredData, int length) {
691693
final XProperty xProperty = inferredData.getProperty();
692694
if ( xProperty != null ) {
693-
GeneratedColumn generatedAnn = xProperty.getAnnotation( GeneratedColumn.class );
695+
GeneratedColumn generatedAnn = getOverridableAnnotation( xProperty, GeneratedColumn.class, context );
694696
if ( generatedAnn != null ) {
695697
if (length!=1) {
696698
throw new MappingException("@GeneratedColumn may only be applied to single-column mappings");
@@ -708,7 +710,7 @@ private void applyGeneratedAs(PropertyData inferredData, int length) {
708710
private void applyCheckConstraint(PropertyData inferredData, int length) {
709711
final XProperty xProperty = inferredData.getProperty();
710712
if ( xProperty != null ) {
711-
Check columnDefaultAnn = xProperty.getAnnotation( Check.class );
713+
Check columnDefaultAnn = AnnotationBinder.getOverridableAnnotation( xProperty, Check.class, context );
712714
if ( columnDefaultAnn != null ) {
713715
if (length!=1) {
714716
throw new MappingException("@Check may only be applied to single-column mappings (use a table-level @Check)");

0 commit comments

Comments
 (0)