grails / gorm-mongodb Goto Github PK
View Code? Open in Web Editor NEWGORM for MongoDB
License: Apache License 2.0
GORM for MongoDB
License: Apache License 2.0
The monolithic grails project has been broken up into several smaller projects. Visit http://github.com/grails.
I've my grails app with below configuration
| Grails Version: 3.2.3
| Groovy Version: 2.4.7
| JVM Version: 1.8.0_121
Build.gradle
compile 'org.grails.plugins:mongodb' // Mongo DB plug-in
application.groovy configuration
grails {
mongodb {
replicaSet = ["mongo-0:27017","mongo-1:27017","mongo-2:27017"]
username = ""
password = ""
databaseName = "mongo-dev"
encryption {
enabled = false
}
}
}
["mongo-0:27017","mongo-1:27017","mongo-2:27017"] is the cluster of mongo db
**If I'm trying to connect to each database individually, It is working fine.
But with replicaSet I'm getting below error**
`
2017-05-17 08:15:55,226 [localhost-startStop-1] INFO org.mongodb.driver.cluster - Cluster created with settings {hosts=[127.0.0.1:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
2017-05-17 08:15:55,253 [cluster-ClusterId{value='591c3efb2568a341831481ec', description='null'}-127.0.0.1:27017] INFO org.mongodb.driver.cluster - Exception in monitor thread while connecting to server 127.0.0.1:27017
com.mongodb.MongoSocketOpenException: Exception opening socket
at com.mongodb.connection.SocketStream.open(SocketStream.java:63)
at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:114)
at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:128)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at com.mongodb.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:50)
at com.mongodb.connection.SocketStream.open(SocketStream.java:58)
... 3 common frames omitted
`
Instead of connecting to mongo cluster of db's, it is trying to connect localhost (i.e. 127.0.0.1:27017)
Please help
When using grails.mongodb.mapping.MappingBuilder.document {}
DSL in a domain class, the following exception is produced:
java.lang.ClassCastException: org.grails.datastore.mapping.keyvalue.mapping.config.Family cannot be cast to org.grails.datastore.mapping.mongo.config.MongoCollection
at org.grails.datastore.mapping.config.AbstractGormMappingFactory.createMappedForm(AbstractGormMappingFactory.java:87)
at org.grails.datastore.mapping.keyvalue.mapping.config.GormKeyValueMappingFactory.createMappedForm(GormKeyValueMappingFactory.java:39)
at org.grails.datastore.mapping.keyvalue.mapping.config.GormKeyValueMappingFactory.createMappedForm(GormKeyValueMappingFactory.java:28)
at org.grails.datastore.mapping.keyvalue.mapping.config.KeyValuePersistentEntity.<init>(KeyValuePersistentEntity.java:35)
at org.grails.datastore.mapping.keyvalue.mapping.config.KeyValueMappingContext.createPersistentEntity(KeyValueMappingContext.java:96)
at org.grails.datastore.mapping.model.AbstractMappingContext.addPersistentEntities(AbstractMappingContext.java:274)
at grails.testing.gorm.DataTest$Trait$Helper.mockDomains(DataTest.groovy:75)
at grails.testing.gorm.DataTest$Trait$Helper.mockDomain(DataTest.groovy:60)
at grails.testing.gorm.DataTest$Trait$Helper.mockDomain(DataTest.groovy:59)
The mapping is defined as:
static final mapping = document {
collection 'myCollection'
sort Query.Order.asc('dateCreated')
}
class Book {
Author author
}
List<Author> authors = ...
Book.where { author in authors }.list()
returns no results
Please allow the ability to use OO Inheritance in Grails domain classes that produce individual Collections in MongoDB per Child Class.
Example Current:
BaseClass -> property1, property2
SubClass -> property3, property4
Expression in MongoDB is:
BaseClass Collection -> class:SubClass, property1, property2, property3(nullable: true), property4(nullable: true)
Preferred Expression In MongoDB:
SubClass Collection -> property1, property2, property3, property4
** This allows us to use OO in Grails domain classes without repercussions in the persistent tier, among other benefits.
THANK YOU for the plugin and for your consideration.
When a property is changed from within class: eg during beforeValidate().
The updated value will not be saved to db unless I explicitely mark the property as dirty or call the setter method on property rather then direct assignment
Example:
class Test {
static mapWith = "mongo"
String value
String computed
static constraints = {
value nullable: false
computed nullable: true
}
def beforeValidate() {
if(id == null || isDirty("value")) computed = value + "-computed"
//markDirty("computed") or setComputed(xxx) will work.
}
}
In above example: when i do
Test test = Test.findByValue(""xxx")
test.value = "new-value"
test.save()
The beforeValidate will be called, the computed property will change, but the changed value will not be persisted to collection.
I guess this has some thing to do with how grails tracks the dirty properties. As this thing works fine with hibernate, i would expect it to work with gorm for mongo too.
Note: This thing does not reproduce in integration tests, you have to do run-app or write a functional test.
I have been refactoring a domain from using an embedded collection into separate collections and encountered an issue with cascading saves. Changes to the child collection are not persisted upon saving the parent domain object. I've tried using markDirty
with no success. The following code recreates the issue. It passes when using an H2 datasource or with an embedded collection.
Grails 3.1.16
gorm-mongo with both 5.0.8 and 6.1.2
Order.groovy
class Order {
ObjectId id
int orderNumber
static hasMany = [items: OrderItem]
}
OrderItem.groovy
class OrderItem {
ObjectId id
String description
static belongsTo = Order
}
Bootstrap.groovy
class BootStrap {
def init = { servletContext ->
int orderNumber = new Random().nextInt()
Order order = new Order(orderNumber: orderNumber)
order.addToItems(new OrderItem(description: 'a product'))
order.save(flush:true)
Order.withNewSession {
order = Order.findByOrderNumber(orderNumber)
order.items.first().description = 'an updated product'
order.markDirty('items')
order.save(flush:true)
}
Order.withNewSession {
order = Order.findByOrderNumber(orderNumber)
assert order.items.first().description == 'an updated product'
}
}
def destroy = {
}
}
When upgrading from Grails 2.4.4 using the MongoDB plugin 3.0.2 to Grails 3.1.6 using the MongoDB plugin version 5.0.5 the withDatabase closure no longer works when authentication is required for the database and the following authentication error is received:
com.mongodb.MongoQueryException: Query failed with error code 13 and error message 'not authorized for query on itemtest.item' on server testdb3:27017
at com.mongodb.connection.ProtocolHelper.getQueryFailureException(ProtocolHelper.java:102)
The application.groovy is configured as follows:
grails {
mongodb {
replicaSet = ["testdb3", "test2db3"]
port = 27017
username = "xxxxxx"
password = "xxxxxx"
databaseName = "testdb"
databaseName_item = "itemtest"
}
}
The code is as follows:
Item.withDatabase(grailsApplication.config.grails.mongodb["databaseName_item"]) {
//query
c.list().iterator() //receive error
}
})
After debugging, in MongoClientFactoryBean.afterPropertiesSet, only one MongoCredential is created with the default database:
if (username != null && password != null) {
credentials.add(MongoCredential.createCredential(username, database, password.toCharArray()));
}
And then the MongoClient is created using that one MongoCredential:
mongo = new MongoClient(replicaSetSeeds, credentials, mongoOptions);
When withDatabase is called, the current MongoClient is retrieved which only had credentials for the default database, not the one we are switching too, thus the authentication error occurs.
It seems that when creating the MongoClient, a MongoCredential should be created for each database listed in the application.groovy file so that when you switch databases with the withDatabase closure the new database is already authenticated.
When using the code below the index is not created:
class Person implements MultiTenant<Person> {
String name
static mapping = {
name index:true
}
}
I have grails app created using 3.2.3 MongoDB plugin 6.0.4 without Hibernate plugin.
I use the following setting in application.yml for mongodb:
grails:
gorm:
failOnError: true
grails:
mongodb:
host: "xxx"
port: 27017
databaseName: "xxx"
There's no exception thrown when call domainInstance.save() on bad data.
But it works fine on calling domainInstance.save(failOnError:true).
This bug has been fixed in MONGO DB plugin 5.0.9, but it reproduced now.
The related bug is grails/grails-data-mapping#734.
The CustomTypeMarshaller
is never invoked with negations. For example, enums:
Domain.withCriteria {
not {
eq("property", SomeEnum.ONE)
}
}
I'm trying to config mongodb 6.0.3 to my current app but I'm getting this error.
I'm using only mongodb as database, so I just commented all about hibernate.
Do I have some missing config?
Thanks in advance.
java.lang.NoClassDefFoundError: org/grails/datastore/gorm/plugin/support/ConfigSupport
error
build.gradle
application.yml
grails:
mongodb:
connectionString: "..."
No longer works in GORM 6. The "url" property replaced it. Both properties should be supported
When using a domain object that has a unique constraint on multiple fields unit tests fail. The application successfully runs and enforces the constraint, the issue is just with unit tests. The same unit tests succeed using hibernate. The error is:
Cannot cast object 'org.grails.datastore.gorm.GormStaticApi@7af24f66' with class 'org.grails.datastore.gorm.GormStaticApi' to class 'org.grails.datastore.gorm.mongo.api.MongoStaticApi'
For example, a domain class Foo:
class Foo {
String name
String value
static constraints = {
name unique: ['value']
}
}
with a corresponding FooSpec test:
@TestFor(Foo)
@Mock(Foo)
class FooSpec extends Specification {
def setup() {
}
def cleanup() {
}
void "test save"() {
given:
new Foo(name: 'foo1', value: 'val1').save(flush:true, failOnError:true)
expect:
Foo.count == 1
}
}
Code is here: https://github.com/bleurubin/testapp/tree/mongo-unique-constraint-bug
Hibernate version that passes here: https://github.com/bleurubin/testapp/tree/hibernate-unique-constraint
Full stacktrace:
Cannot cast object 'org.grails.datastore.gorm.GormStaticApi@7af24f66' with class 'org.grails.datastore.gorm.GormStaticApi' to class 'org.grails.datastore.gorm.mongo.api.MongoStaticApi'
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'org.grails.datastore.gorm.GormStaticApi@7af24f66' with class 'org.grails.datastore.gorm.GormStaticApi' to class 'org.grails.datastore.gorm.mongo.api.MongoStaticApi'
at grails.mongodb.MongoEntity$Trait$Helper.currentMongoStaticApi(MongoEntity.groovy:263)
at grails.mongodb.MongoEntity$Trait$Helper.createCriteria(MongoEntity.groovy:129)
at org.grails.datastore.gorm.validation.constraints.UniqueConstraint.findExisting(UniqueConstraint.groovy:101)
at org.grails.datastore.gorm.validation.constraints.UniqueConstraint.processValidate_closure1(UniqueConstraint.groovy:76)
at org.grails.datastore.gorm.validation.constraints.UniqueConstraint.withManualFlushMode_closure4(UniqueConstraint.groovy:133)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:430)
at org.grails.datastore.gorm.GormStaticApi.withSession_closure21(GormStaticApi.groovy:819)
at groovy.lang.Closure.call(Closure.java:414)
at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:318)
at org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:40)
at org.grails.datastore.gorm.GormStaticApi.withSession(GormStaticApi.groovy:818)
at org.grails.datastore.gorm.GormEntity$Trait$Helper.withSession(GormEntity.groovy:889)
at org.grails.datastore.gorm.validation.constraints.UniqueConstraint.withManualFlushMode(UniqueConstraint.groovy:128)
at org.grails.datastore.gorm.validation.constraints.UniqueConstraint.processValidate(UniqueConstraint.groovy:46)
at grails.validation.AbstractConstraint.validate(AbstractConstraint.java:107)
at grails.validation.ConstrainedProperty.validate(ConstrainedProperty.java:979)
at org.grails.validation.GrailsDomainClassValidator.validatePropertyWithConstraint(GrailsDomainClassValidator.java:206)
at org.grails.validation.GrailsDomainClassValidator.validate(GrailsDomainClassValidator.java:81)
at org.grails.datastore.gorm.GormValidationApi.doValidate(GormValidationApi.groovy:116)
at org.grails.datastore.gorm.GormValidationApi.validate(GormValidationApi.groovy:197)
at org.grails.datastore.gorm.GormValidateable$Trait$Helper.validate(GormValidateable.groovy:91)
at org.grails.datastore.gorm.GormInstanceApi.doSave(GormInstanceApi.groovy:327)
at org.grails.datastore.gorm.GormInstanceApi.save_closure5(GormInstanceApi.groovy:177)
at groovy.lang.Closure.call(Closure.java:414)
at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:318)
at org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:40)
at org.grails.datastore.gorm.GormInstanceApi.save(GormInstanceApi.groovy:176)
at org.grails.datastore.gorm.GormEntity$Trait$Helper.save(GormEntity.groovy:151)
at testapp.FooSpec.test save(FooSpec.groovy:22)
I am trying to switch between different connection using "withConnection" as mentioned here:http://gorm.grails.org/6.0.x/whatsNew/manual/ but I end up getting following error
No signature of method: mgmigration.ChangeSet.withConnection() is applicable for argument types: (java.lang.String, mgmigration.MigrateService$__tt__executeChangeSet_closure2) values:
I do have "org.grails.plugins:hibernate5" dependency commented out so I am not using hibernate and in my domain object I have specified both connections properly.
package mgmigration
import org.bson.types.ObjectId
class ChangeSet {
ObjectId id
String author
String comment
String migrationClassName
String revision
Date dateCreated
Date lastUpdated
static mapping = {
mapWith "mongo"
connections analytics, reporting
collection "migrationChangeSet"
id attr: "_id"
autoTimestamp true
version false
}
}
And my application.yml has connections params properly defined too.
mongodb:
connections:
analytics:
url: 'mongodb://${MONGODB_USERNAME}:${MONGODB_PASSWORD}@${MONGODB_REPLICA_SET}/${MONGODB_ANALYTICS_DATABASE}?${MONGODB_CONNECTION_OPTIONS}'
reporting:
url: 'mongodb://${MONGODB_USERNAME}:${MONGODB_PASSWORD}@${MONGODB_REPLICA_SET}/${MONGODB_REPORTING_DATABASE}?${MONGODB_CONNECTION_OPTIONS}'
I am using mongodb plugin 'org.grails.plugins:mongodb:6.0.7' and grails 3.2.6
This issue has been detected in Grails 3.2.5 - GORM 6.0.6
When a uni- or bi-directional parent-child association is mapped as cascade:none this mapping is ignored, and changes to child instances are cascaded on parent save().
This behavior contradicts the GORM manual, which states (6.4 Understanding Cascading Updates):
So exactly like the previous case of a undirectional One-to-Many, without belongsTo definition no delete operations will be cascaded, but crucially saves and updates will by default. If you do not want saves and updates to cacade then you must alter the cascade policy of A:
class A {
static hasMany = [bees: B]
static mapping = {
bees cascade:"none"
}
}
Here is a test case to replicate. Add to the SimpleHasManySpec suite:
@Entity
class BookNoCascade implements Serializable {
ObjectId id
Long version
static hasMany = [chapters: BiChapter]
String name
Set<Chapter> chapters
static mapping = {
chapters cascade: "none"
}
}
void "Test save unidirectional one-to-many with cascade:none does not cascade changes to its children"() {
when:"A domain model is persisted with a dirty child instance"
String origTitle = "first"
def c1 = new Chapter(title: origTitle)
def c1Persisted = c1.save(flush:true)
Long origVersion = c1Persisted.version
session.clear()
def book = new BookNoCascade(name: "mybook")
book.chapters = new HashSet()
c1.title = 'firstUpdated'
book.chapters.add(c1)
book.save(flush:true)
session.clear()
book = BookNoCascade.get(book.id)
then:"The retrieved data is correct"
def c1AfterSave = book.chapters.find { it.id == c1.id }
c1AfterSave != null
origVersion == c1AfterSave.version // the version should stay at 0
origTitle == c1AfterSave.title // the title should stay "first"
}
This test will fail with:
Condition not satisfied:
origVersion == c1AfterSave.version // the version should stay at 0
| | | |
0 | | 1
| org.grails.datastore.gorm.mongo.BiChapter : 58a22e10bcb2a6399b00b1c3
falseExpected :1
Actual :0
A similar test for a bi-directional association also fails (not quoted here).
This behavior results in unnecessary datastore updates and increases the risk of concurrent modification errors (optimistic locking errors).
NOTE: If the cascade type 'none' is not supported by GORM for Mongo then such a mapping should produce an error at the registration time. Having this type supported, however, would be much more preferable as it is useful. As an example, one scenario is where such a parent-child association instance is automatically constructed from JSON where the child data is guaranteed immutable.
Iam using grails 3.2.9 and gorm mongodb plugin 6.1.2 and mongo driver 3.4.2
@GrailsCompileStatic
class GrowthAnalysis {
ObjectId id
String symbol
Date lastUpdated
List<HistoricalData> historicalData
Long updatedYear
PEData peData
static embedded = ['historicalData','peData']
static constraints = {
peData(nullable:true)
}
}
@GrailsCompileStatic
class PEData {
ObjectId id
Map<String,BigDecimal> growthInBookValue
static constraints = {
growthInBookValue(nullable:true)
}
static embedded = ['growthInBookValue']
when I save growthAnalysis on gorm save method it will save perfetcly.
while retriving growthAnaysis object by find () method
def ga = GrowthAnalysis.findBySymbol(symbol)
it will throw the exception
Caused by: java.util.NoSuchElementException: Cannot access first() element from an empty List
I am using grails 3.2.9 and gormMongo version 6.1.2 and mongo driver 3.1.2. Mongo db server version 3.4.7. when I insert the
documents in low level by using doc.put('price',new BigDecimal(value)). while saving It throw the exception .
org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class java.math.BigDecimal
MongoDB has an async driver.
http://mongodb.github.io/mongo-java-driver/3.6/driver-async/
Wouldn't it play nice with Async GORM? If so, this could be an interesting choice
I tried to follow the instructions here: http://gorm.grails.org/6.1.2/mongodb/manual/#_removal_of_grails_datastore_simple
But I can't get the unit tests to run, I just get a stacktrace.
Example project here: https://github.com/jakecoffman/grails2mongo
Stacktrace when running unit tests:
java.lang.AbstractMethodError: org.grails.datastore.mapping.core.AbstractDatastore.createSession(Lorg/springframework/core/env/PropertyResolver;)Lorg/grails/datastore/mapping/core/Session;
at org.grails.datastore.mapping.core.AbstractDatastore.connect(AbstractDatastore.java:134)
at org.grails.datastore.mapping.core.AbstractDatastore.connect(AbstractDatastore.java:130)
at grails.test.runtime.DomainClassTestPlugin.connectDatastore(DomainClassTestPlugin.groovy:88)
at grails.test.runtime.DomainClassTestPlugin.before(DomainClassTestPlugin.groovy:104)
at grails.test.runtime.DomainClassTestPlugin.onTestEvent(DomainClassTestPlugin.groovy:123)
at grails.test.runtime.TestRuntime.deliverEvent(TestRuntime.groovy:295)
at grails.test.runtime.TestRuntime.processEvents(TestRuntime.groovy:264)
at grails.test.runtime.TestRuntime.doPublishEvent(TestRuntime.groovy:248)
at grails.test.runtime.TestRuntime.publishEvent(TestRuntime.groovy:211)
at grails.test.runtime.TestRuntimeJunitAdapter.before(TestRuntimeJunitAdapter.groovy:109)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426)
at grails.test.runtime.TestRuntimeJunitAdapter$1$2.evaluate(TestRuntimeJunitAdapter.groovy:47)
at org.spockframework.runtime.extension.builtin.TestRuleInterceptor.intercept(TestRuleInterceptor.java:38)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:88)
at org.spockframework.runtime.extension.builtin.AbstractRuleInterceptor$1.evaluate(AbstractRuleInterceptor.java:37)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426)
at grails.test.runtime.TestRuntimeJunitAdapter$3$4.evaluate(TestRuntimeJunitAdapter.groovy:76)
at org.spockframework.runtime.extension.builtin.ClassRuleInterceptor.intercept(ClassRuleInterceptor.java:38)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.codehaus.groovy.grails.test.spock.GrailsSpecTestType.doRun(GrailsSpecTestType.groovy:147)
at org.codehaus.groovy.grails.test.support.GrailsTestTypeSupport.run(GrailsTestTypeSupport.groovy:121)
at org.codehaus.groovy.grails.test.runner.GrailsProjectTestRunner.runTests(GrailsProjectTestRunner.groovy:415)
at org.codehaus.groovy.grails.test.runner.GrailsProjectTestRunner.processTests(GrailsProjectTestRunner.groovy:395)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426)
at org.codehaus.groovy.grails.test.runner.GrailsProjectTestRunner.runAllTests_closure7(GrailsProjectTestRunner.groovy:314)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426)
at groovy.lang.Closure.call(Closure.java:414)
at org.codehaus.groovy.grails.test.runner.GrailsProjectTestRunner.runAllTests(GrailsProjectTestRunner.groovy:300)
at org.codehaus.groovy.grails.test.runner.GrailsProjectTestRunner.runAllTests(GrailsProjectTestRunner.groovy:215)
at org.codehaus.groovy.grails.cli.fork.testing.ForkedGrailsTestRunner.runInstance(ForkedGrailsTestRunner.groovy:128)
at org.codehaus.groovy.grails.cli.fork.ForkedGrailsProjectClassExecutor.run(ForkedGrailsProjectClassExecutor.groovy:74)
at org.codehaus.groovy.grails.cli.fork.testing.ForkedGrailsTestRunner.main(ForkedGrailsTestRunner.groovy:75)
Given the following domain classes:
@Entity
class BatchAddress {
Long id
String name
static mapping = {
version false
}
}
@Entity
class BatchUser {
Long id
BatchAddress address
static mapping = {
version false
}
}
And the following operation:
BatchUser.where { address == oldAddress }.updateAll(address: newAddress)
Future queries are incorrect (assuming 2 old and 1 new previous to the udpate)
BatchUser.where { address == newAddress }.count() == 3
BatchUser.where { address == oldAddress }.count() == 3
Running into an issue with querying my user collection now that I've transitioned all my updates to low level mongodb and I'm not using grails built in user.save() method. I've looked at the users in the database with MongoHub and everything looks as it should.
Here's the criteria search:
def c = User.createCriteria() User user = c.get { or { and { eq "email", emailUsernameCommand.emailUsername eq "password", passEncrypted } and { eq "username", emailUsernameCommand.emailUsername eq "password", passEncrypted } } }
New accounts work normally, previously created accounts are generating the following error.
ERROR AccountService - Unable to authenticate user test : readDateTime can only be called when CurrentBSONType is DATE_TIME, not when CurrentBSONType is STRING. org.bson.BsonInvalidOperationException: readDateTime can only be called when CurrentBSONType is DATE_TIME, not when CurrentBSONType is STRING. at org.bson.AbstractBsonReader.verifyBSONType(AbstractBsonReader.java:655) at org.bson.AbstractBsonReader.checkPreconditions(AbstractBsonReader.java:687) at org.bson.AbstractBsonReader.readDateTime(AbstractBsonReader.java:288) at org.grails.datastore.mapping.mongo.engine.codecs.PersistentEntityCodec$SimpleDecoder$8.decode(PersistentEntityCodec.groovy:670) at org.grails.datastore.mapping.mongo.engine.codecs.PersistentEntityCodec$SimpleDecoder.decode(PersistentEntityCodec.groovy:721) at org.grails.datastore.mapping.mongo.engine.codecs.PersistentEntityCodec$SimpleDecoder.decode(PersistentEntityCodec.groovy) at org.grails.datastore.mapping.mongo.engine.codecs.PersistentEntityCodec.decode(PersistentEntityCodec.groovy:159) at com.mongodb.operation.CommandResultArrayCodec.decode(CommandResultArrayCodec.java:48) at com.mongodb.operation.CommandResultDocumentCodec.readValue(CommandResultDocumentCodec.java:53) at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:81) at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:40) at org.bson.codecs.configuration.LazyCodec.decode(LazyCodec.java:47) at org.bson.codecs.BsonDocumentCodec.readValue(BsonDocumentCodec.java:98) at com.mongodb.operation.CommandResultDocumentCodec.readValue(CommandResultDocumentCodec.java:56) at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:81) at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:40) at com.mongodb.connection.CommandProtocol.execute(CommandProtocol.java:123) at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:159) at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:286) at com.mongodb.connection.DefaultServerConnection.command(DefaultServerConnection.java:173) at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:215) at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:206) at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:112) at com.mongodb.operation.FindOperation$1.call(FindOperation.java:485) at com.mongodb.operation.FindOperation$1.call(FindOperation.java:480) at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:239) at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:212) at com.mongodb.operation.FindOperation.execute(FindOperation.java:480) at com.mongodb.operation.FindOperation.execute(FindOperation.java:77) at com.mongodb.Mongo.execute(Mongo.java:772) at com.mongodb.Mongo$2.execute(Mongo.java:759) at com.mongodb.OperationIterable.iterator(OperationIterable.java:47) at com.mongodb.FindIterableImpl.iterator(FindIterableImpl.java:143) at org.grails.datastore.mapping.mongo.query.MongoQuery.executeQuery(MongoQuery.java:1019) at org.grails.datastore.mapping.mongo.query.MongoQuery.executeQuery(MongoQuery.java:882) at org.grails.datastore.mapping.query.Query.list(Query.java:567) at org.grails.datastore.mapping.query.Query.singleResult(Query.java:585) at grails.gorm.CriteriaBuilder.get(CriteriaBuilder.java:297) at org.grails.datastore.mapping.query.api.BuildableCriteria$get.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
Assuming the following domain classes:
class Pet {
static mapping = {
index( [ "_class": 1] )
}
}
class Dog extends Pet {
}
Actual:
When the app starts it will create a collection for both Dog
and Pet
and create the index in both.
Expected:
The collection and index should only be created for Pet
Bug reproducible here: https://github.com/jakecoffman/grails3-mongo-bug
The project inserts two Authors in the Bootstrap, but if you hit /authors
only 1 is listed.
It has something to do with storing a list of strings inside of a Map on the domain. If you create Authors that don't put Lists in Maps then they all render just fine.
I have reproduced this under grails 2 as well.
If a there is a hasMany
relationship to another domain class, and that collection is embedded, provide a configuration option to tell GORM to assign an id to items as they are added in the collection.
Using multi tenant approach at database level. Domain classes gets saved correctly in respective tenant databases however for these domain classes version column is not saved. Which means optimistic lock exception is thrown when such an object is updated.
Sample project to reproduce scenario
Grails Version: 3.0.1
Groovy Version: 2.4.3
JVM Version: 1.8.0_31
'org.grails.plugins:mongodb:6.0.4'
Details:
Domain class which implements "MongoEntity, MultiTenant" traits, when such a domain class is saved as:
Tenants.withCurrent {
book.save(flush: true)
}
then version column is not saved. Version column gets saved if we remove the " implemetns MongoEntity, MultiTenant" from domain class, but then class gets saved in default database and not the tenant one. Highly appreciate your help.
I migrated to Grails 3.2.0.RC2 from 3.0.1 adding support for multi tenancy.
If i add connection as ALL in the domain class as described in the doc,
class ZipCode {
String code
static mapping = {
connection ConnectionSource.ALL
}
}
I end up with this compilation errors.
org.grails.datastore.mapping.core.exceptions.ConfigurationException: Invalid connection [ALL] configured for class.
If i use ConnectionSource.DEFAULT or don't define mapping, the code compiles and run, but its not going to tenant's database.
Do I have to add this mapping to all the domain objects in which i need multi tendency feature?
There seems to be actually two issues:
In integration tests:
hasChanged/isDirty always seem to return true for every property
In running app
hasChanged/isDirty works for regular properties
but for property of type other domains, hasChaned will return true even if the referenced domain has not changed
See attached sample, it has a DirtyPropertiesSpec which fails
contentful-bug-report-30062017.zip
In our app, after the databinding (which has parameter "parent.id" = xxx)
if i check, hasChanged("parent") it returns true, even if the parent object is same
This thing works fine with hibernate, if u remove the static mapWith = "mongo"
from domain, and run the test again, it will pass the isDirty() checks, but not hasChanged() checks
When an error occurs within a transaction that spans multiple services, saves that occur prior to the error are not rolled back. The saves are not flushing the transaction. It looks like Transactions aren't explicitly supported in mongo, if this is expected behavior maybe it should be called out in the documentation:
http://gorm.grails.org/latest/mongodb/manual/index.html#transactions
I also tried it across multiple services with the same type of domain object and behavior was the same.
mongo test showing the issue: https://github.com/bleurubin/testapp/tree/mongo-transactions-bug
hibernate test that correctly rolls back the transaction: https://github.com/bleurubin/testapp/tree/hibernate-transactions-1
@Entity
class Comment {
Long id
String text
List<Comment> replies
static belongsTo = [parent: Comment]
static hasMany = [replies: Comment]
}
new Comment(text: "Hello")
.addToReplies(text: "World")
.addToReplies(text: "!")
.save(flush:true)
Comment.findByText("World").delete(flush:true)
That results in all comments of the parent to be deleted.
Updates on objects of nested embedded lists take really long. I use a model where cells are embedded in rows and those rows are themselves embedded in a block.
Block
List<Row> rows
static embedded = ['rows']
Row
List<Cell> cells
static embedded = ['cells']
Update to cell properties
Block block = Block.get(new ObjectId(jsonObject.block_id))
Row row = block.rows[rowIdx]
Cell cell = row.cells[colIdx]
cell.text = text
cell.state = state
block.save(failOnError: true, flush: true)
On update, the version number in the db of all rows and all cells is increased by 2. The version of the block is increased by 1. This leads to really slow execution times on larger blocks.
In the documentation for the latest version of the plugin 6.1.4 there is a section on how the datasource-simple dependency has been removed. There are instructions for Grails 3.x on how to handle this (http://gorm.grails.org/latest/mongodb/manual/#upgradeNotes) but there isn't the equivalent for Grails 2.x
The following test fails with owner.dogs[0].toys[0].dog != null
class EmbeddedBiDirectionalSpec extends GormDatastoreSpec {
void "test nested backreferences"() {
when:"A domain is created with nested embedded collections"
def owner = new EBDDogOwner(name: "Joe")
EBDDog dog = new EBDDog(name: "Rex")
dog.addToToys(manufacturer: 'Mattel')
owner.addToDogs(dog)
owner.save(flush: true)
session.clear()
owner = EBDDogOwner.findByName("Joe")
then:"All entities are saved with back references"
owner != null
owner.dogs.size() == 1
owner.dogs[0].owner != null
owner.dogs[0].toys.size() == 1
owner.dogs[0].toys[0].dog != null
}
@Override
List getDomainClasses() {
[EBDDogOwner, EBDDog, EBDToy]
}
}
@Entity
class EBDDogOwner {
String name
static hasMany = ['dogs': EBDDog]
static embedded = ['dogs']
}
@Entity
class EBDDog {
String name
static belongsTo = ['owner': EBDDogOwner]
static hasMany = ['toys': EBDToy]
static embedded = ['toys']
}
@Entity
class EBDToy {
String manufacturer
static belongsTo = ['dog': EBDDog]
}
Grails BugReport: rdbms_mongo-bug-report-06112017.zip
Version: Grails 3.3.1, GORM 6.1.7.RELEASE
Worked in: Grails 3.2.9, GORM 6.0.10.RELEASE
Background
I've got an app with Hibernate and Mongo. While my domain objects are slightly unusual (they implement a java interface and have methods that return Publishers), this code used to work with 3.2.9. Upgrading to 3.3.1 breaks it.
Reproduction
When I run ./grailsw run-app
or ./gradlew bootRun
, I get this exception
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '5a0146e9c4f090d4c3950012' with class 'java.lang.String' to class 'org.grails.datastore.mapping.dirty.checking.DirtyCheckable'
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:405)
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:319)
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:232)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.java:603)
at org.grails.datastore.mapping.mongo.engine.MongoCodecEntityPersister.processAssociations(MongoCodecEntityPersister.groovy:327)
at org.grails.datastore.mapping.mongo.engine.MongoCodecEntityPersister.persistEntity(MongoCodecEntityPersister.groovy:217)
at org.grails.datastore.mapping.mongo.engine.MongoCodecEntityPersister.persistEntity(MongoCodecEntityPersister.groovy:534)
at org.grails.datastore.mapping.engine.EntityPersister.persist(EntityPersister.java:183)
at org.grails.datastore.mapping.core.AbstractSession.persist(AbstractSession.java:598)
at org.grails.datastore.gorm.GormInstanceApi.doSave(GormInstanceApi.groovy:364)
at org.grails.datastore.gorm.GormInstanceApi.doSave(GormInstanceApi.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
Other info
id
.String id
with ObjectId id
. That didn't help much.Given a domain class whose id is defined as org.bson.types.ObjectId
, when doing DomainClass.get("123")
, a NPE is thrown at org.grails.datastore.mapping.core.AbstractSession.retrieve(AbstractSession.java:633)
.
We are using Grails 3.2.11 with mongodb (GORM version 6.0.12.RELEASE) in our REST application. MongoDB version is 3.4.
The problem is we are getting Optimistic Locking very frequently and since we are not able to replicate it in our local and staging environment it is very hard to debug the issue.
In our production environment, it throws Optimistic locking with HTTP Status 500 which eventually crashes our backend.
I saw it has been fixed and closed in https://github.com/grails/grails-data-mapping/issues/180, but am not sure whether the issue has been resurfaced or what?
If not, then what would be the better way to handle this exception?
When I'm trying to convert mongo entity using grails.converter.JSON, it's throwing the following exception Could not retrieve the respective entity for domain Workspace in the mapping context API
.
Dependency:
//grailsVersion 3.3.1
compile "org.grails.plugins:converters"
compile 'org.grails.plugins:mongodb:6.1.4'
compile "org.mongodb:mongodb-driver:3.5.0"
Domain class:
class Workspace {
static mapWith = "mongo"
ObjectId id
String name
List<ObjectId> formIds
long companyId
static mapping = {
collection 'eform_workspace'
}
}
Service code snippet:
List<Workspace> workspaces = Workspace.findAll()
String workspaceJson = workspaces as JSON // produces exception
return [
workspacesJson: workspaceJson
]
Stacktrace:
Caused by: java.lang.RuntimeException: org.grails.core.exceptions.GrailsConfigurationException: Could not retrieve the respective entity for domain Workspace in the mapping context API
at org.grails.web.converters.AbstractConverter.toString(AbstractConverter.java:120)
at org.codehaus.groovy.runtime.typehandling.ShortTypeHandling.castToString(ShortTypeHandling.java:44)
at com.example.artifact.form.service.EformHomeService$$EQcpF3wG.$tt__getUserWorkspaces(EformHomeService.groovy:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springsource.loaded.ri.ReloadedTypeInvoker$2.invoke(ReloadedTypeInvoker.java:133)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1462)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:925)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:908)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethodSafe(InvokerHelper.java:76)
at com.example.artifact.form.service.EformHomeService$_getUserWorkspaces_closure1$$EQcpF3wG.doCall(EformHomeService.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springsource.loaded.ri.ReloadedTypeInvoker$2.invoke(ReloadedTypeInvoker.java:133)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1462)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at groovy.lang.Closure.call(Closure.java:414)
at com.example.artifact.form.service.EformHomeService$_getUserWorkspaces_closure1.call(EformHomeService.groovy)
at groovy.lang.Closure.call(Closure.java:430)
at com.example.artifact.form.service.EformHomeService$_getUserWorkspaces_closure1.call(EformHomeService.groovy)
at grails.gorm.transactions.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:94)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at grails.gorm.transactions.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:91)
at com.example.artifact.form.service.EformHomeService$$EQcpF3wG.getUserWorkspaces(EformHomeService.groovy)
at com.example.artifact.form.service.EformHomeService$$DQcpF3wG.getUserWorkspaces(Unknown Source)
at com.example.artifact.form.service.EformHomeService.getUserWorkspaces(EformHomeService.groovy)
at com.example.artifact.form.service.EformHomeService$getUserWorkspaces$0.call(Unknown Source)
... 98 common frames omitted
class RuleBase {
String ruleBaseName
Decimal128 deMinimusValueInsured
Decimal128 deMinimusValueUninsured
Decimal128 manualReviewLimit
}
I am trying to use Decimal128
instead of BigDecimal
but I am getting this exception when calling RuleBase.list()
of any other query. No errors when saving.
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [org.bson.types.Decimal128]
If I look into mongo I see that the Decimal128
properties are saved as String
.
In my good'ol grails (3.1.x) app I have lines like
ModuleState.collection.updateOne(
[ compositeKey:ck ],
[ $set:[ compositeKey:ck, dateUpdated:new Date(), online:true ] ],
[ upsert:true ] )
In my grails-free app with GORM standalone:
compile 'org.grails:grails-datastore-gorm-mongodb:6.0.4.RELEASE'
this line throws an exception
groovy.lang.MissingMethodException: No signature of method: com.mongodb.MongoCollectionImpl.updateOne() is applicable for argument types: (java.util.LinkedHashMap, java.util.LinkedHashMap, java.util.LinkedHashMap) values: [[compositeKey:111], [$set:[...]], ...] Possible solutions: updateOne(org.bson.conversions.Bson, org.bson.conversions.Bson), updateOne(org.bson.conversions.Bson, org.bson.conversions.Bson, com.mongodb.client.model.UpdateOptions)
so, the new map-consuming methods are not injected.
I have the following domain objects
import org.bson.types.ObjectId
class Person {
ObjectId id
String firstName
String lastName
Map<String,Address> addresses
static embedded = ['addresses']
}
import org.bson.types.ObjectId
class Address {
ObjectId id
String addressLine
String addressLine2
String street
}
I write the code to create the person object with empty address
Person person=new Person()
person.firstName='SADASIVA'
person.lastName='GOLI'
person.save(flush:true)
It is saved in the collection as
{
"_id" : ObjectId("5a21233d5cc6962b24afb675"),
"firstName" : "SADASIVA",
"lastName" : "GOLI",
"version" : NumberLong(5)
}
For updating the person Address I write the follwing logic
Person person=Person.findByFirstName('SADASIVA')
Address paddress=new Address()
paddress.addressLine='Desaipeta1'
paddress.addressLine2='marrishettu'
paddress.street='shanthinagar'
Map<String,Address> map=new HashMap<String,Address>()
map.put('perminentAddress',paddress)
person.addresses=map
person.save(flush:true)
The above code will not persist the address in the database while updating. How can we resolve this.
For Fresh new Object saving it is save the map (addresses property) also.
Thanks,
SADASIVAIAH GOLI
Using GORM-mongo (standalone):
String gormVer = '6.1.2.RELEASE'
dependencies{
compile "org.grails:grails-datastore-gorm-mongodb:$gormVer"
compile "org.grails:grails-datastore-gorm-mongodb-ext:$gormVer"
}
and domain class:
@entity
class Timeline {
String id
List< Integer > minutes = []
List< Map > actions = []
static embedded = [ 'minutes', 'actions' ]
}
In the code:
Timeline.withSession{
Timeline timeline = Timeline.get someId
timeline.minutes << 10
//timeline.actions << [:]
timeline.save flush:true //<< this line is throwing exception
}
If I uncomment the line, the exception is thrown upon saving:
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'org.grails.datastore.bson.codecs.CodecExtensions$MapCodec@1c762333' with class 'org.grails.datastore.bson.codecs.CodecExtensions$MapCodec' to class 'org.grails.datastore.mapping.mongo.engine.codecs.PersistentEntityCodec'
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:405)
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:319)
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:232)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.java:603)
at org.grails.datastore.mapping.mongo.engine.codecs.PersistentEntityCodec.encodeEmbeddedCollectionUpdate(PersistentEntityCodec.groovy:396)
at org.grails.datastore.mapping.mongo.engine.codecs.PersistentEntityCodec.encodeUpdate(PersistentEntityCodec.groovy:254)
at org.grails.datastore.mapping.mongo.engine.codecs.PersistentEntityCodec.encodeUpdate(PersistentEntityCodec.groovy)
at org.grails.datastore.mapping.mongo.MongoCodecSession.flush(MongoCodecSession.groovy:158)
at org.grails.datastore.mapping.mongo.AbstractMongoSession.flush(AbstractMongoSession.java:74)
at org.grails.datastore.gorm.GormInstanceApi.doSave(GormInstanceApi.groovy:367)
at org.grails.datastore.gorm.GormInstanceApi.doSave(GormInstanceApi.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1215)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)
at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:923)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:906)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethodSafe(InvokerHelper.java:74)
at org.grails.datastore.gorm.GormInstanceApi$_save_closure5.doCall(GormInstanceApi.groovy:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)
at groovy.lang.Closure.call(Closure.java:414)
at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:54)
at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:124)
at com.sun.proxy.$Proxy36.doInSession(Unknown Source)
at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:319)
at org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:40)
at org.grails.datastore.gorm.GormInstanceApi.save(GormInstanceApi.groovy:178)
at org.grails.datastore.gorm.GormEntity$Trait$Helper.save(GormEntity.groovy:152)
at org.grails.datastore.gorm.GormEntity$Trait$Helper$save$4.call(Unknown Source)
at io.mozaiq.domain.Timeline.save(Timeline.groovy)
at io.mozaiq.domain.Timeline.save(Timeline.groovy)
at org.grails.datastore.gorm.GormEntity$save.call(Unknown Source)
at io.mozaiq.logic.Processor$_updateTimeline_closure8.doCall(Processor.groovy:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:430)
at org.grails.datastore.gorm.GormStaticApi$_withSession_closure21.doCall(GormStaticApi.groovy:811)
at sun.reflect.GeneratedMethodAccessor25.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)
at groovy.lang.Closure.call(Closure.java:414)
at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:54)
at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:124)
at com.sun.proxy.$Proxy36.doInSession(Unknown Source)
at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:319)
at org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:40)
at org.grails.datastore.gorm.GormStaticApi.withSession(GormStaticApi.groovy:810)
at org.grails.datastore.gorm.GormEntity$Trait$Helper.withSession(GormEntity.groovy:889)
at org.grails.datastore.gorm.GormEntity$Trait$Helper$withSession$2.call(Unknown Source)
at io.mozaiq.domain.Timeline.withSession(Timeline.groovy)
at io.mozaiq.domain.Timeline$withSession$1.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at io.mozaiq.domain.Timeline$withSession$1.call(Unknown Source)
at io.mozaiq.logic.Processor.updateTimeline(Processor.groovy:96)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSite.invoke(PogoMetaMethodSite.java:169)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.call(PogoMetaMethodSite.java:71)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133)
at io.mozaiq.logic.LogicUnitVerticle$_start_closure2.doCall(LogicUnitVerticle.groovy:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)
at groovy.lang.Closure.call(Closure.java:414)
at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:54)
at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:124)
at com.sun.proxy.$Proxy37.handle(Unknown Source)
at io.vertx.core.eventbus.impl.HandlerRegistration.deliver(HandlerRegistration.java:212)
at io.vertx.core.eventbus.impl.HandlerRegistration.handle(HandlerRegistration.java:191)
at io.vertx.core.eventbus.impl.EventBusImpl.lambda$deliverToHandler$3(EventBusImpl.java:524)
at io.vertx.core.impl.ContextImpl.lambda$wrapTask$2(ContextImpl.java:337)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:403)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:445)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
at java.lang.Thread.run(Thread.java:745)
When domain class is mapped with mongo and extends from abstract class, then the fields defined in the abstract class are never marked as dirty when their value is changed.
Example: https://github.com/mugren/abstract-dirty-vanilla
Aside that after calling save on the domain object the method domainObject.getDirtyPropertyNames() includes the className of the instance as list item too.
Edit: tested with mongodb:5.0.10 version of the plugin
Git repo with tests showing failures:
https://github.com/mvniekerk/vertxgormfail
Book.createCriteria.get {
eq("title", "THE STAND", [ignoreCase: true])
}
Will fail if using GORM with mongo, though works with hibernate. I'm not sure how the hibernate options would/could map to mongo.
Discovered in Grails 3.2.5 - Gorm 6.0.6
Assigning a property of a persisted domain instance to null and saving the instance results in the old (non-null) value retained in the data store.
This is caused by the check condition at line 263 in PersistentEntityCodec only collecting unset operations for embedded domain types.
Here is a test case to replicate the issue. Add to DirtyCheckUpdateSpec suite add:
void "Test unsetting a property through dirty check"() {
given:"A domain instance"
def b = new Bar(foo:"stuff")
b.save(flush:true)
session.clear()
when:"The domain is updated with a null property value"
b = Bar.get(b.id)
b.foo == 'stuff'
b.setProperty('foo', null)
b.isDirty()
b.isDirty('foo')
b.save(flush:true)
session.clear()
b = Bar.get(b.id)
then:"the update did unset the nulled property"
b.foo == null
b instanceof DirtyCheckable
}
The test fails with an unsatisfied condition:
Condition not satisfied:
b.foo == null
| | |
| | false
| stuff
org.grails.datastore.gorm.mongo.Bar : 589a4089bcb2a66b00f802d9
NOTE: It appears the same issue is present in the BsonPersistentEntityCodec (line 256).
I believe this is a serious issue as it prevents from resetting domain properties on update.
We have a Grails 2.5.6 application that connects to a Mongo database that is being upgraded to 3.4. As I understand it this requires moving to the 6.1.2 version of the Grails MongoDB plugin. This has been completed for the application and it works. However, the application also connects to an Oracle DB and uses Hibernate. With a fork configuration similar to the following the application works fine when running locally (run-app or through IntelliJ).
grails.project.fork = [
test: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, daemon:true],
run: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, forkReserve:false],
war: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, forkReserve:false],
console: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256]
]
However, when deploying as a WAR to a Tomcat container it fails with the following error at startup. I can recreate this locally by removing the fork configuration.
Caused by ClassNotFoundException: org.springframework.context.PayloadApplicationEvent
->> 179 | findClass in org.codehaus.groovy.tools.RootLoader
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 425 | loadClass in java.lang.ClassLoader
| 151 | loadClass in org.codehaus.groovy.tools.RootLoader
| 358 | loadClass in java.lang.ClassLoader
| 151 | <init> . in org.grails.orm.hibernate.HibernateDatastore
| 262 | run in java.util.concurrent.FutureTask
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run . . . in java.lang.Thread
I took a look at the Spring version being pulled in by Grails 2.5.6, 4.1.9, and sure enough the class in question is not present. Spring 4.1.9 documentation. It looks like the class is first present in 4.2.0 documentation.
Here is a snippet of the BuildConfig.groovy:
grails.project.dependency.resolver = "maven" // or ivy
grails.project.dependency.resolution = {
// inherit Grails' default dependencies
inherits("global") {
// specify dependency exclusions here; for example, uncomment this to disable ehcache:
// excludes 'ehcache'
excludes 'grails-plugin-testing', 'grails-plugin-rest', 'grails-plugin-filters', 'grails-plugin-url-mappings', 'grails-plugin-async', 'grails-plugin-gsp'
}
log "error" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'
checksums true // Whether to verify checksums on resolve
legacyResolve false // whether to do a secondary resolve on plugin installation, not advised and here for backwards compatibility
repositories {
inherits true // Whether to inherit repository definitions from plugins
grailsPlugins()
grailsHome()
mavenLocal()
grailsCentral()
mavenCentral()
}
dependencies {
compile('org.codehaus.groovy.modules.http-builder:http-builder:0.7.2') {
excludes 'commons-logging', 'xml-apis', 'groovy'
}
compile 'javax.mail:mail:1.4'
compile ('org.grails:grails-plugin-rest:2.5.6') { excludes 'grails-datastore-simple' }
compile ('org.grails:grails-plugin-filters:2.5.6') { excludes 'grails-datastore-simple' }
compile ('org.grails:grails-plugin-url-mappings:2.5.6') { excludes 'grails-datastore-simple' }
compile ('org.grails:grails-plugin-async:2.5.6') { excludes 'grails-datastore-simple' }
compile ('org.grails:grails-plugin-gsp:2.5.6') { excludes 'grails-datastore-simple' }
test ('org.grails:grails-plugin-testing:2.5.3') { excludes 'grails-datastore-simple' }
test 'org.grails:grails-datastore-gorm-test:6.1.1.RELEASE'
test 'org.grails:grails-datastore-test-support:5.0.13.RELEASE'
test 'com.github.fakemongo:fongo:2.1.0'
runtime 'joda-time:joda-time:2.4'
runtime 'com.oracle:ojdbc6:11.2.0.3'
}
plugins {
// plugins for test
test ':code-coverage:2.0.3-3'
test ':build-test-data:2.2.3'
// plugins for the build system only
build ':tomcat:8.0.22'
// plugins for the compile step
compile ':rest:0.8'
compile ':cache:1.1.8'
compile ':cache-ehcache:1.0.5'
compile ':mongodb:6.1.2'
compile ':marshallers:0.6'
compile ':cache-manager:1.0.0'
compile ':rabbitmq-native:3.1.3'
// plugins needed at runtime but not for compilation
runtime (':hibernate4:6.1.2') {
excludes 'grails-datastore-simple'
excludes 'ehcache-core'
}
runtime ':resources:1.2.14'
}
Any thoughts? I apologize if this should have been posted somewhere else. Thanks for any guidance you can provide.
For inheritance class hierarchy object mapping, calling the list() method in the base class is returning objects from the derived classes as well as the base class. For example, if Pet is the base class and Cat and Dog extends Pet, calling Pet.list() is returning objects created from the Cat and Dog classes.
Please see the following Github repository to reproduce the problem: https://github.com/tatleung/gorm-inheritance-test
There are 2 branches in the repository: the mongodb branch will help reproduce the problem. The mysql branch verifies the same use case is working correctly in MySQL.
Added a failing test with the PR #26
Currently, there are four types of drivers for MongoDB in Java world:
The last one could, maybe, be the base for a RSGORM (GORM for Reactive Streams).
If a document has a reference to another domain class and the document for that domain class cannot found, it should return null instead of throwing an exception. Add as a configuration option to prevent breaking existing behavior
Adding a BigDecimal to a basic collection in an entity fails with the error:
Can't find a codec for class java.math.BigDecimal.
Doubles work.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.