Skip to content

Commit 7088b2d

Browse files
committed
Merge branch 'master' of github.com:grails/grails-core
2 parents dc1a2a8 + 8c847c5 commit 7088b2d

File tree

7 files changed

+214
-10
lines changed

7 files changed

+214
-10
lines changed

src/java/org/codehaus/groovy/grails/commons/GrailsDomainConfigurationUtil.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ public static Map<String, ConstrainedProperty> evaluateConstraints(final Class<?
396396
// specified otherwise by the constraints
397397
// If the field is a Java entity annotated with @Entity skip this
398398
applyDefaultConstraints(propertyName, p, cp,
399-
defaultConstraints, delegate.getSharedConstraint(propertyName));
399+
defaultConstraints, delegate.getSharedConstraint(propertyName), propertyConfig);
400400
}
401401
}
402402
}
@@ -451,7 +451,7 @@ public static Map<String, ConstrainedProperty> evaluateConstraints(Class<?> theC
451451

452452
@SuppressWarnings("unchecked")
453453
private static void applyDefaultConstraints(String propertyName, GrailsDomainClassProperty p,
454-
ConstrainedProperty cp, Map<String, Object> defaultConstraints, String sharedConstraintReference) {
454+
ConstrainedProperty cp, Map<String, Object> defaultConstraints, String sharedConstraintReference, PropertyConfig propertyConfig) {
455455

456456
if (defaultConstraints != null && !defaultConstraints.isEmpty()) {
457457
if (defaultConstraints.containsKey("*")) {
@@ -473,10 +473,14 @@ private static void applyDefaultConstraints(String propertyName, GrailsDomainCla
473473
}
474474

475475
if (canApplyNullableConstraint(propertyName, p, cp)) {
476-
cp.applyConstraint(ConstrainedProperty.NULLABLE_CONSTRAINT,
477-
Collection.class.isAssignableFrom(p.getType()) ||
478-
Map.class.isAssignableFrom(p.getType())
479-
);
476+
if (propertyConfig!=null && !propertyConfig.getInsertable()) {
477+
cp.applyConstraint(ConstrainedProperty.NULLABLE_CONSTRAINT,true);
478+
} else {
479+
cp.applyConstraint(ConstrainedProperty.NULLABLE_CONSTRAINT,
480+
Collection.class.isAssignableFrom(p.getType()) ||
481+
Map.class.isAssignableFrom(p.getType())
482+
);
483+
}
480484
}
481485
}
482486

src/java/org/codehaus/groovy/grails/orm/hibernate/cfg/GrailsDomainBinder.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2118,8 +2118,8 @@ private static void bindProperty(GrailsDomainClassProperty grailsProperty, Prope
21182118
prop.setInsertable(false);
21192119
prop.setUpdateable(false);
21202120
} else {
2121-
prop.setInsertable(true);
2122-
prop.setUpdateable(true);
2121+
prop.setInsertable(getInsertableness(grailsProperty));
2122+
prop.setUpdateable(getUpdateableness(grailsProperty));
21232123
}
21242124

21252125
prop.setPropertyAccessorName(mappings.getDefaultAccess());
@@ -2149,6 +2149,18 @@ private static boolean getLazyiness(GrailsDomainClassProperty grailsProperty) {
21492149
return isLazy;
21502150
}
21512151

2152+
private static boolean getInsertableness(GrailsDomainClassProperty grailsProperty) {
2153+
PropertyConfig config = getPropertyConfig(grailsProperty);
2154+
final boolean isInsertable = config!=null ? config.getInsertable() : true;
2155+
return isInsertable;
2156+
}
2157+
2158+
private static boolean getUpdateableness(GrailsDomainClassProperty grailsProperty) {
2159+
PropertyConfig config = getPropertyConfig(grailsProperty);
2160+
final boolean isUpdateable = config!=null ? config.getUpdateable() : true;
2161+
return isUpdateable;
2162+
}
2163+
21522164
private static boolean isBidirectionalManyToOneWithListMapping(GrailsDomainClassProperty grailsProperty, Property prop) {
21532165
GrailsDomainClassProperty otherSide = grailsProperty.getOtherSide();
21542166
return grailsProperty.isBidirectional() && otherSide != null && prop.getValue() instanceof ManyToOne && List.class.isAssignableFrom(otherSide.getType());

src/java/org/codehaus/groovy/grails/orm/hibernate/cfg/HibernateMappingBuilder.groovy

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,8 @@ class HibernateMappingBuilder {
368368
property.formula = namedArgs.formula
369369
property.type = namedArgs.type ?: property.type
370370
property.lazy = namedArgs.lazy != null ? namedArgs.lazy : property.lazy
371+
property.insertable = namedArgs.insertable != null ? namedArgs.insertable : property.insertable
372+
property.updateable = namedArgs.updateable != null ? namedArgs.updateable : property.updateable
371373
property.cascade = namedArgs.cascade ?: property.cascade
372374
property.sort = namedArgs.sort ?: property.sort
373375
property.order = namedArgs.order ?: property.order

src/java/org/codehaus/groovy/grails/orm/hibernate/cfg/PropertyConfig.groovy

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,19 @@ class PropertyConfig {
7070
*/
7171
boolean ignoreNotFound = false
7272

73+
74+
75+
/**
76+
* Whether or not this is column is insertable by hibernate
77+
*/
78+
boolean insertable = true
79+
80+
81+
/**
82+
* Whether or not this column is updateable by hibernate
83+
*/
84+
boolean updateable = true
85+
7386
/**
7487
*
7588
*/
@@ -161,7 +174,7 @@ class PropertyConfig {
161174
}
162175

163176
String toString() {
164-
"property[type:$type, lazy:$lazy, columns:$columns]"
177+
"property[type:$type, lazy:$lazy, columns:$columns, insertable:${insertable}, updateable:${updateable}]"
165178
}
166179

167180
private void checkHasSingleColumn() {

src/test/org/codehaus/groovy/grails/commons/GrailsDomainConfigurationUtilTests.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,22 @@
1414
*/
1515
package org.codehaus.groovy.grails.commons;
1616

17+
import groovy.lang.ExpandoMetaClass;
18+
import groovy.lang.GroovyClassLoader;
19+
1720
import java.net.URI;
1821
import java.net.URL;
1922
import java.util.Date;
23+
import java.util.Map;
2024

2125
import junit.framework.TestCase;
2226

27+
import org.codehaus.groovy.grails.orm.hibernate.cfg.DefaultGrailsDomainConfiguration;
28+
import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinder;
29+
import org.codehaus.groovy.grails.validation.ConstrainedProperty;
30+
import org.codehaus.groovy.grails.validation.NullableConstraint;
31+
import org.hibernate.cfg.ImprovedNamingStrategy;
32+
2333
/**
2434
* Tests for the GrailsDomainConfigurationUtil class.
2535
*
@@ -28,6 +38,18 @@
2838
*/
2939
public class GrailsDomainConfigurationUtilTests extends TestCase {
3040

41+
@Override
42+
protected void setUp() throws Exception {
43+
super.setUp();
44+
ExpandoMetaClass.enableGlobally();
45+
}
46+
47+
@Override
48+
protected void tearDown() throws Exception {
49+
super.tearDown();
50+
GrailsDomainBinder.namingStrategy = ImprovedNamingStrategy.INSTANCE;
51+
}
52+
3153
public void testIsBasicType() {
3254
assertTrue(GrailsDomainConfigurationUtil.isBasicType(boolean.class));
3355
assertTrue(GrailsDomainConfigurationUtil.isBasicType(long.class));
@@ -65,4 +87,39 @@ public void testIsBasicType() {
6587
assertTrue(GrailsDomainConfigurationUtil.isBasicType(Float[].class));
6688
assertTrue(GrailsDomainConfigurationUtil.isBasicType(Byte[].class));
6789
}
90+
91+
public void testEvaluateConstraintsInsertableShouldBeNullableByDefault() {
92+
GroovyClassLoader cl = new GroovyClassLoader();
93+
GrailsDomainClass domainClass = new DefaultGrailsDomainClass(
94+
cl.parseClass(
95+
"class TestInsertableUpdateableDomain {\n" +
96+
" Long id \n" +
97+
" Long version \n" +
98+
" String testString1 \n" +
99+
" String testString2 \n"+
100+
"\n" +
101+
" static mapping = {\n" +
102+
" testString1 insertable:false \n" +
103+
" testString2 max:50 \n" +
104+
" }\n" +
105+
"}")
106+
);
107+
108+
getDomainConfig(cl, new Class[] { domainClass.getClazz() });
109+
Map<String, ConstrainedProperty> mapping = GrailsDomainConfigurationUtil.evaluateConstraints(domainClass.getClazz(),domainClass.getProperties(),null);
110+
ConstrainedProperty property1 = mapping.get("testString1");
111+
assertTrue("constraint was not nullable and should be", ((NullableConstraint)property1.getAppliedConstraint(ConstrainedProperty.NULLABLE_CONSTRAINT)).isNullable());
112+
ConstrainedProperty property2 = mapping.get("testString2");
113+
assertFalse("constraint was nullable and shouldn't be", ((NullableConstraint)property2.getAppliedConstraint(ConstrainedProperty.NULLABLE_CONSTRAINT)).isNullable());
114+
115+
}
116+
117+
private DefaultGrailsDomainConfiguration getDomainConfig(GroovyClassLoader cl, Class<?>[] classes) {
118+
GrailsApplication grailsApplication = new DefaultGrailsApplication(classes, cl);
119+
grailsApplication.initialise();
120+
DefaultGrailsDomainConfiguration config = new DefaultGrailsDomainConfiguration();
121+
config.setGrailsApplication(grailsApplication);
122+
config.buildMappings();
123+
return config;
124+
}
68125
}

src/test/org/codehaus/groovy/grails/orm/hibernate/HibernateMappingBuilderTests.groovy

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,4 +717,24 @@ class HibernateMappingBuilderTests extends GroovyTestCase {
717717
assertEquals "valueParam1", mapping.getPropertyConfig('value').typeParams.param1
718718
assertEquals 21, mapping.getPropertyConfig('value').typeParams.param2
719719
}
720+
721+
void testInsertablePropertyConfig() {
722+
def builder = new HibernateMappingBuilder("Foo")
723+
def mapping = builder.evaluate {
724+
firstName insertable:true
725+
lastName insertable:false
726+
}
727+
assertTrue mapping.getPropertyConfig('firstName').insertable
728+
assertFalse mapping.getPropertyConfig('lastName').insertable
729+
}
730+
731+
void testUpdatablePropertyConfig() {
732+
def builder = new HibernateMappingBuilder("Foo")
733+
def mapping = builder.evaluate {
734+
firstName updateable:true
735+
lastName updateable:false
736+
}
737+
assertTrue mapping.getPropertyConfig('firstName').updateable
738+
assertFalse mapping.getPropertyConfig('lastName').updateable
739+
}
720740
}

src/test/org/codehaus/groovy/grails/orm/hibernate/cfg/GrailsDomainBinderTests.java

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@
2424
import java.util.Arrays;
2525
import java.util.Iterator;
2626
import java.util.List;
27+
import java.util.Set;
28+
import java.lang.reflect.Field;
2729

2830
import junit.framework.TestCase;
29-
3031
import org.codehaus.groovy.grails.commons.DefaultGrailsApplication;
3132
import org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass;
3233
import org.codehaus.groovy.grails.commons.GrailsApplication;
@@ -297,6 +298,101 @@ public void testUniqueConstraintGeneration() {
297298
assertEquals(true, found2);
298299
}
299300

301+
public void testInsertableHibernateMapping() throws Exception {
302+
GroovyClassLoader cl = new GroovyClassLoader();
303+
GrailsDomainClass domainClass = new DefaultGrailsDomainClass(
304+
cl.parseClass(
305+
"class TestInsertableDomain {\n" +
306+
" Long id \n" +
307+
" Long version \n" +
308+
" String testString1 \n" +
309+
" String testString2 \n" +
310+
"\n" +
311+
" static mapping = {\n" +
312+
" testString1 insertable:false \n" +
313+
" testString2 insertable:true \n" +
314+
" }\n" +
315+
"}")
316+
);
317+
318+
DefaultGrailsDomainConfiguration config = getDomainConfig(cl,
319+
new Class[] { domainClass.getClazz() });
320+
Field privateDomainClasses = DefaultGrailsDomainConfiguration.class.
321+
getDeclaredField("domainClasses");
322+
privateDomainClasses.setAccessible(true);
323+
Set domainClasses = (Set) privateDomainClasses.get(config);
324+
325+
GrailsDomainClass domainClassObj = (GrailsDomainClass)domainClasses.iterator().next();
326+
327+
PersistentClass persistentClass = config.getClassMapping("TestInsertableDomain");
328+
329+
Property property1 = persistentClass.getProperty("testString1");
330+
assertEquals(false,property1.isInsertable());
331+
332+
Property property2 = persistentClass.getProperty("testString2");
333+
assertEquals(true,property2.isInsertable());
334+
}
335+
336+
public void testUpdateableHibernateMapping() throws Exception {
337+
GroovyClassLoader cl = new GroovyClassLoader();
338+
GrailsDomainClass domainClass = new DefaultGrailsDomainClass(
339+
cl.parseClass(
340+
"class TestInsertableDomain {\n" +
341+
" Long id \n" +
342+
" Long version \n" +
343+
" String testString1 \n" +
344+
" String testString2 \n" +
345+
"\n" +
346+
" static mapping = {\n" +
347+
" testString1 updateable:false \n" +
348+
" testString2 updateable:true \n" +
349+
" }\n" +
350+
"}")
351+
);
352+
353+
DefaultGrailsDomainConfiguration config = getDomainConfig(cl,
354+
new Class[] { domainClass.getClazz() });
355+
356+
PersistentClass persistentClass = config.getClassMapping("TestInsertableDomain");
357+
358+
Property property1 = persistentClass.getProperty("testString1");
359+
assertEquals(false,property1.isUpdateable());
360+
361+
Property property2 = persistentClass.getProperty("testString2");
362+
assertEquals(true,property2.isUpdateable());
363+
}
364+
365+
public void testInsertableUpdateableHibernateMapping() throws Exception {
366+
GroovyClassLoader cl = new GroovyClassLoader();
367+
GrailsDomainClass domainClass = new DefaultGrailsDomainClass(
368+
cl.parseClass(
369+
"class TestInsertableUpdateableDomain {\n" +
370+
" Long id \n" +
371+
" Long version \n" +
372+
" String testString1 \n" +
373+
" String testString2 \n" +
374+
"\n" +
375+
" static mapping = {\n" +
376+
" testString1 insertable:false, updateable:false \n" +
377+
" testString2 updateable:false, insertable:false \n" +
378+
" }\n" +
379+
"}")
380+
);
381+
382+
DefaultGrailsDomainConfiguration config = getDomainConfig(cl,
383+
new Class[] { domainClass.getClazz() });
384+
385+
PersistentClass persistentClass = config.getClassMapping("TestInsertableUpdateableDomain");
386+
387+
Property property1 = persistentClass.getProperty("testString1");
388+
assertEquals(false,property1.isInsertable());
389+
assertEquals(false,property1.isUpdateable());
390+
391+
Property property2 = persistentClass.getProperty("testString2");
392+
assertEquals(false,property2.isUpdateable());
393+
assertEquals(false,property2.isInsertable());
394+
}
395+
300396
public void testOneToOneBindingTables() {
301397
DefaultGrailsDomainConfiguration config = getDomainConfig(ONE_TO_ONE_CLASSES_DEFINITION);
302398
assertEquals("Tables created", 2, getTableCount(config));

0 commit comments

Comments
 (0)