Skip to content

Commit f575638

Browse files
committed
Merge remote-tracking branch 'origin/7.0.x'
# Conflicts: # build.gradle
2 parents 4d6ec52 + 912eef7 commit f575638

File tree

6 files changed

+158
-7
lines changed

6 files changed

+158
-7
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ project.ext {
2121
projectPatchVersion = "0"
2222
// releaseType = "RELEASE"
2323
// releaseType = "M2"
24-
// releaseType = "RC1"
24+
// releaseType = "RC1"
2525
releaseType = "BUILD-SNAPSHOT"
2626

2727
// overall project version
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package grails.gorm.tests
2+
3+
import grails.gorm.annotation.Entity
4+
import org.grails.datastore.mapping.proxy.ProxyHandler
5+
6+
class BuiltinUniqueConstraintWorksWithTargetProxiesConstraintsSpec extends GormDatastoreSpec {
7+
8+
void "test unique constraint on root instance"() {
9+
10+
setup:
11+
ContactDetails contactDetails1 = new ContactDetails(phoneNumber: "+1-202-555-0105").save(failOnError: true)
12+
ContactDetails contactDetails2 = new ContactDetails(phoneNumber: "+1-202-555-0105")
13+
session.flush()
14+
session.clear()
15+
16+
when: "I try to validate the another object"
17+
contactDetails2.validate()
18+
19+
then: "another should have an error on name because it is duplicated"
20+
contactDetails2.hasErrors()
21+
contactDetails2.errors.hasFieldErrors("phoneNumber")
22+
contactDetails2.errors.getFieldError("phoneNumber").codes.contains("unique.phoneNumber")
23+
24+
cleanup:
25+
ContactDetails.deleteAll(contactDetails1)
26+
}
27+
28+
void "test unique constraint for the associated child object"() {
29+
30+
setup:
31+
ContactDetails contactDetails1 = new ContactDetails(phoneNumber: "+1-202-555-0105").save(failOnError: true)
32+
Patient patient1 = new Patient(contactDetails: contactDetails1).save(failOnError: true)
33+
session.flush()
34+
session.clear()
35+
36+
when:
37+
Patient patient2 = new Patient(contactDetails: new ContactDetails(phoneNumber: "+1-202-555-0105"))
38+
patient2.validate()
39+
40+
then:
41+
patient2.hasErrors()
42+
patient2.errors.hasFieldErrors("contactDetails.phoneNumber")
43+
patient2.errors.getFieldError("contactDetails.phoneNumber").codes.contains("unique.phoneNumber")
44+
45+
cleanup:
46+
Patient.deleteAll(patient1)
47+
ContactDetails.deleteAll(contactDetails1)
48+
}
49+
50+
void "test unique constraint on the unmodified association loaded as initialized proxy"() {
51+
52+
setup:
53+
final ProxyHandler proxyHandler = session.mappingContext.getProxyHandler()
54+
ContactDetails contactDetails = new ContactDetails(phoneNumber: "+1-202-555-0105").save(failOnError: true)
55+
Patient patient = new Patient(contactDetails: contactDetails).save(failOnError: true)
56+
Long patientId = patient.id
57+
session.flush()
58+
session.clear()
59+
60+
when:
61+
patient = Patient.get(patientId)
62+
patient.contactDetails.phoneNumber = "+1-202-555-0105"
63+
64+
then:
65+
proxyHandler.isProxy(patient.contactDetails)
66+
67+
expect:
68+
patient.validate()
69+
70+
cleanup:
71+
Patient.deleteAll(patient)
72+
ContactDetails.deleteAll(patient.contactDetails)
73+
}
74+
75+
@Override
76+
List getDomainClasses() {
77+
[ContactDetails, Patient]
78+
}
79+
}
80+
81+
@Entity
82+
class ContactDetails implements Serializable {
83+
84+
String phoneNumber
85+
86+
static constraints = {
87+
phoneNumber nullable: false, unique: true
88+
}
89+
}
90+
91+
@Entity
92+
class Patient implements Serializable {
93+
94+
ContactDetails contactDetails
95+
96+
static constraints = {
97+
contactDetails nullable: false
98+
}
99+
100+
static mapping = {
101+
contactDetails lazy: true
102+
}
103+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package grails.gorm.tests
2+
3+
4+
import org.grails.datastore.mapping.proxy.ProxyHandler
5+
6+
class ProxyInitializationSpec extends GormDatastoreSpec {
7+
8+
@Override
9+
List getDomainClasses() {
10+
[Patient, ContactDetails]
11+
}
12+
13+
void "test if proxy is initialized"() {
14+
15+
setup:
16+
final ProxyHandler proxyHandler = session.mappingContext.getProxyHandler()
17+
ContactDetails contactDetails = new ContactDetails(phoneNumber: "+1-202-555-0178").save(failOnError: true)
18+
Long patientId = new Patient(contactDetails: contactDetails).save(failOnError: true).id
19+
session.flush()
20+
session.clear()
21+
22+
when:
23+
Patient patient = Patient.get(patientId)
24+
25+
then:
26+
proxyHandler.isProxy(patient.contactDetails)
27+
28+
when:
29+
patient.contactDetails.phoneNumber = "+1-202-555-0178"
30+
31+
then:
32+
proxyHandler.isInitialized(patient.contactDetails)
33+
34+
cleanup:
35+
Patient.deleteAll(patient)
36+
ContactDetails.deleteAll(patient.contactDetails)
37+
}
38+
}

grails-datastore-gorm/src/main/groovy/org/grails/datastore/gorm/validation/constraints/builtin/UniqueConstraint.groovy

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,17 @@ class UniqueConstraint extends AbstractConstraint {
138138
if (shouldValidate) {
139139
def existingId = detachedCriteria.get()
140140
if (existingId != null) {
141-
def targetId = reflector.getIdentifier(target)
141+
// We are merely verifying that the object is not transient here
142+
def targetId
143+
if (proxyHandler.isProxy(target)) {
144+
if (proxyHandler.isInitialized(target)) {
145+
targetId = reflector.getIdentifier(proxyHandler.unwrap(target))
146+
} else {
147+
targetId = proxyHandler.getIdentifier(target)
148+
}
149+
} else {
150+
targetId = reflector.getIdentifier(target)
151+
}
142152
if (targetId != existingId) {
143153
def args = [constraintPropertyName, constraintOwningClass, propertyValue] as Object[]
144154
rejectValue(target, errors, "unique", args, getDefaultMessage("default.not.unique.message"))

travis-build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ else
1313
./gradlew --no-daemon --refresh-dependencies check || EXIT_STATUS=$?
1414
if [[ $EXIT_STATUS -eq 0 && $TRAVIS_PULL_REQUEST == 'false' ]]; then
1515
echo "Travis Branch $TRAVIS_BRANCH"
16-
if ([[ -n $TRAVIS_TAG ]] || [[ $TRAVIS_BRANCH == 'master' ]] && [[ "${TRAVIS_JDK_VERSION}" != "openjdk11" ]]); then
16+
if ([[ -n $TRAVIS_TAG ]] || [[ $TRAVIS_BRANCH =~ ^master|[7]\..\.x$ ]] && [[ "${TRAVIS_JDK_VERSION}" != "openjdk11" ]]); then
1717
./travis-publish.sh || EXIT_STATUS=$?
1818
fi
1919
fi

travis-publish.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ if [[ $TRAVIS_REPO_SLUG == "grails/grails-data-mapping" && $TRAVIS_PULL_REQUEST
3131
echo "https://$GH_TOKEN:@github.com" > ~/.git-credentials
3232

3333
echo "Triggering Hibernate 5 build"
34-
git clone -b master https://${GH_TOKEN}@github.com/grails/gorm-hibernate5.git gorm-hibernate5
34+
git clone -b $TRAVIS_BRANCH https://${GH_TOKEN}@github.com/grails/gorm-hibernate5.git gorm-hibernate5
3535
cd gorm-hibernate5
3636
echo "$(date)" > .snapshot
3737
git add .snapshot
@@ -40,7 +40,7 @@ if [[ $TRAVIS_REPO_SLUG == "grails/grails-data-mapping" && $TRAVIS_PULL_REQUEST
4040
cd ..
4141

4242
echo "Triggering Neo4j build"
43-
git clone https://${GH_TOKEN}@github.com/grails/gorm-neo4j.git gorm-neo4j
43+
git clone -b $TRAVIS_BRANCH https://${GH_TOKEN}@github.com/grails/gorm-neo4j.git gorm-neo4j
4444
cd gorm-neo4j
4545
echo "$(date)" > .snapshot
4646
git add .snapshot
@@ -49,7 +49,7 @@ if [[ $TRAVIS_REPO_SLUG == "grails/grails-data-mapping" && $TRAVIS_PULL_REQUEST
4949
cd ..
5050

5151
echo "Triggering MongoDB build"
52-
git clone https://${GH_TOKEN}@github.com/grails/gorm-mongodb.git gorm-mongodb
52+
git clone -b $TRAVIS_BRANCH https://${GH_TOKEN}@github.com/grails/gorm-mongodb.git gorm-mongodb
5353
cd gorm-mongodb
5454
echo "$(date)" > .snapshot
5555
git add .snapshot
@@ -91,4 +91,4 @@ fi
9191
if [[ $EXIT_STATUS -eq 0 ]]; then
9292
echo "Publishing Successful."
9393
fi
94-
exit $EXIT_STATUS
94+
exit $EXIT_STATUS

0 commit comments

Comments
 (0)