unable to insert document in mongo using gmongo - grails

I have the following code to insert a document in groovy but I keep getting this error in grails applications
def zipcode = getDocumentCollection()
zipcode.insert(["city": "ACMAR", "loc": [-86.51557F, 33.584132F], "pop": 6055, "state": "AL", "_id": "35004"])
No signature of method: com.mongodb.DBApiLayer$MyCollection.insert()
is applicable for argument types: (java.util.LinkedHashMap) values:
[[city:ACMAR, loc:[-86.51557, 33.584133], ...]] Possible solutions:
insert([Lcom.mongodb.DBObject;), insert(java.util.List),
insert([Lcom.mongodb.DBObject;, com.mongodb.WriteConcern),
insert(com.mongodb.DBObject, com.mongodb.WriteConcern),
insert(com.mongodb.WriteConcern, [Lcom.mongodb.DBObject;),
insert(java.util.List, com.mongodb.WriteConcern)
this code is taken from the example of gmongo. Any ideas why I'm getting an error ?
UPDATE
I get the below error in Grails app after trying #dmahapatro's approach:
2013-06-06 09:54:21,493 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing the application: Error creating bean with name 'org.springframework.data.mongodb.monitor.OperationCounters#0': Unsatisfied dependency expressed through constructor argument with index 0 of type [com.mongodb.Mongo]: Could not convert constructor argument value of type [com.gmongo.GMongo] to required type [com.mongodb.Mongo]: Failed to convert value of type 'com.gmongo.GMongo' to required type 'com.mongodb.Mongo'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [com.gmongo.GMongo] to required type [com.mongodb.Mongo]: no matching editors or conversion strategy found
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.data.mongodb.monitor.OperationCounters#0': Unsatisfied dependency expressed
through constructor argument with index 0 of type [com.mongodb.Mongo]: Could not convert constructor argument value of type [com.gmongo.GMongo] to required type [com.mongodb.Mongo]: Failed to
convert value of type 'com.gmongo.GMongo' to required type 'com.mongodb.Mongo'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [com.gmongo.GMongo] to required type [com.mongodb.Mongo]: no matching editors or conversion strategy found
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

When you use insert you need to provide the key-value pairs as named args (I think you can also use a map but it will be less verbose).
zipcode.insert(city: "ACMAR", loc: [-86.51557F, 33.584132F], pop: 6055, state: "AL", _id: "35004")
If you want to use a HashMap then use the left-shift operator to insert documents into collection.
zipcode << ["city": "ACMAR", "loc": [-86.51557F, 33.584132F], "pop": 6055, "state": "AL", "_id": "35004"]
I would go with the second approach if I were using aggregation.
Sample
This works perfect for me when tested.
#Grab(group='com.gmongo', module='gmongo', version='1.0')
import com.gmongo.GMongo
def mongo = new GMongo("127.0.0.1", 27017)
def db = mongo.getDB("gmongo")
//Instead of doing below I can also use db.zipcodes.insert(blah: blah)
def zipCode = db.getCollection("zipcodes")
zipCode.insert(city: "ACMAR", loc: [-86.51557F, 33.584132F], pop: 6055, state: "AL", _id: "35004")
zipCode << [city: "DUMMY", loc: [-86.51587F, 33.584172F], pop: 6056, state: "AL", _id: "35005"]
assert db.zipcodes.findOne(city: "DUMMY").city == 'DUMMY'
assert db.zipcodes.findOne(city: "ACMAR").city == 'ACMAR'

Related

deserialization issue, with json.net, in F#

I have a simple object to deserialize, but I do not understand the error I get.
The code is the following:
open System
open Newtonsoft.Json
type r =
{
Timestamp: DateTime
Currency: string
PreviousDeposited: int64 option
PreviousWithdrawn: int64 option
PreviousTransferIn: int64 option
PreviousTransferOut: int64 option
PreviousAmount: int64 option
TransferIn: int64 option
TransferOut: int64 option
Amount: int64 option
PendingCredit: int64 option
PendingDebit: int64 option
ConfirmedDebit: int64 option
}
let a =
"{
\"account\": 117122,
\"currency\": \"XBt\",
\"prevDeposited\": 747841316,
\"prevWithdrawn\": 2160000,
\"prevTransferIn\": 1000000,
\"prevTransferOut\": 0,
\"prevAmount\": 656893723,
\"prevTimestamp\": \"2020-06-13T12:00:00.005Z\",
\"deltaDeposited\": 0,
\"deltaWithdrawn\": 0,
\"deltaTransferIn\": 0,
\"deltaTransferOut\": 0,
\"deltaAmount\": 0,
\"deposited\": 747841316,
\"withdrawn\": 2160000,
\"transferIn\": 1000000,
\"transferOut\": 0,
\"amount\": 656893723,
\"pendingCredit\": 0,
\"pendingDebit\": 0,
\"confirmedDebit\": 0,
\"timestamp\": \"2020-06-13T12:00:00.643Z\",
\"addr\": \"2NBMEXRW4oCiNzVUq4uVFRSsK2jtTLbtfc7\",
\"script\": \"532102c10be2f0dc20f4285c25156aa22a0c46d2b89ccc4d1c8eaed92ea0c1a8f40c002102ceba29da1af96a0f2ef7cda6950b8be2baeb1adf12c0d5efebb70dbcaa086ba021034ab762f4ede40311e9f8bf01db0bbea578497ac6ccc8aa94a74394b05a53d94b2103d5a42b90e9d7156155661979530a09d2e12e252ef4104e5611274a7ae7e2b09454ae\",
\"withdrawalLock\": []
}"
JsonConvert.DeserializeObject<r> a
and I get this error:
Newtonsoft.Json.JsonSerializationException: Unexpected property
'transferOut' found when reading union. Path 'transferOut', line 18,
position 18.] at
Newtonsoft.Json.Converters.DiscriminatedUnionConverter.ReadJson(JsonReader
reader, Type objectType, Object existingValue, JsonSerializer
serializer) at
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter
converter, JsonReader reader, Type objectType, Object existingValue)
at
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ResolvePropertyAndCreatorValues(JsonObjectContract
contract, JsonProperty containerProperty, JsonReader reader, Type
objectType) at
...
I do not understand what makes the property 'TransferOut' so special that it stops on this one, and not on any of the other identical ones before.
I have a fiddle here: https://dotnetfiddle.net/HGiia5
You have a few problems here.
Firstly, the JSON syntax you are using for an option field does not match Json.NET's syntax. If we simplify your type as follows:
type r =
{
TransferIn: int64 option
TransferOut: int64 option
}
And serialize an instance as follows:
let item : r = { TransferIn = Some 1000000L; TransferOut = None}
let json = JsonConvert.SerializeObject(item,Formatting.Indented)
printfn "%s" json
let item2 = JsonConvert.DeserializeObject<r> json // No exception
The result is:
{
"TransferIn": {
"Case": "Some",
"Fields": [
1000000
]
},
"TransferOut": null
}
Which round-trips successfully. Demo fiddle #1 here.
The simple syntax "transferIn": 1000000 you are using for option fields is not implemented by DiscriminatedUnionConverter, the converter that Json.NET uses for serializing discriminated unions including optional fields. This mismatch is causing an exception while reading the JSON.
Relatedly, see Serializing F# Option types which has a suggestion for a nuget package that provides a JsonConverter for option<_> that supports this simplified syntax.
Secondly, many of the JSON property names do not match your f# record names. Json.NET uses an ordinal-case-insensitive algorithm to match JSON property names to f# constructor arguments and member names, but many of your JSON names do not match:
"prevDeposited" does not match PreviousDeposited.
"prevWithdrawn" does not match PreviousWithdrawn.
And several others.
In fact the first property in the JSON that actually matches an option field is "transferIn". You are receiving an error about "transferOut" because it immediately follows the value of "transferIn" which was not deserialized successfully.
Finally, the error message that Json.NET is throwing for invalid JSON values for option fields is non-useful when the field does not appear at the end of a JSON object. If I simplify the input JSON as follows:
{
"transferIn": 1000000,
}
The we get a much more useful error message
Newtonsoft.Json.JsonSerializationException: No 'Case' property with union name found. Path '', line 3, position 1.
Demo fiddle #2 here.
But when "transferIn" is followed by another JSON key/value pair the error message becomes the less useful message shown in your question. You might open an issue with Newtonsoft asking them to improve the error message that DiscriminatedUnionConverter throws when the JSON value for an option field does not match the expected schema and there are subsequent JSON properties in the containing object.

Neo4j-OGM/Spring-Data-Neo4j: Migrate property type from Integer to String

In a large database I have to change the data type of a property for a type of nodes from Integer to String (i.e. 42 to "42") in order to also support non-numerical IDs.
I've managed to do the migration itself and the property now has the expected type in the database.
I have verified this using the Neo4j-Browsers ability to show the query result as JSON:
"graph": {
"nodes": [
{
"id": "4190",
"labels": [
"MyEntity"
],
"properties": {
"id": "225"
}
}
}
Note that the "id" property is different from the node's own (numerical) id.
In the corresponding Spring-Data-Neo4j 4app, I adjusted the type of the corresponding property from Integer to String as well. I expected that to be enough, however upon first loading an affected entity I now receive:
org.neo4j.ogm.exception.MappingException: Error mapping GraphModel to instance of com.example.MyEntity
[...]
Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: Can not set java.lang.String field de.moneysoft.core.model.base.UriEntity.transfermarktId to java.lang.Integer
at org.neo4j.ogm.entity.io.FieldWriter.write(FieldWriter.java:43)
at org.neo4j.ogm.entity.io.FieldWriter.write(FieldWriter.java:68)
at org.neo4j.ogm.context.GraphEntityMapper.writeProperty(GraphEntityMapper.java:232)
at org.neo4j.ogm.context.GraphEntityMapper.setProperties(GraphEntityMapper.java:184)
at org.neo4j.ogm.context.GraphEntityMapper.mapNodes(GraphEntityMapper.java:151)
at org.neo4j.ogm.context.GraphEntityMapper.mapEntities(GraphEntityMapper.java:135)
... 122 common frames omitted
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.String field com.example.MyEntity.id to java.lang.Integer
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
at java.lang.reflect.Field.set(Field.java:764)
at org.neo4j.ogm.entity.io.FieldWriter.write(FieldWriter.java:41)
... 127 common frames omitted
I am not aware of Neo4j-OGM storing any kind of model or datatype (at least I don't see it in the graph). Why does it still believe that my property is an Integer?
Edit:
Node Entity after migration:
#NodeEntity
public class MyEntity
{
#Property
protected String name;
#Property
private String id;
}
I am not aware of any other relevant code.
Well, if the error you see looks implausible, it probably is.
After a good nights sleep, I realized that I had connected to the wrong database instance: Not the one that was migrated and that I was looking at in the browser, but another one that contained an unmigrated state.
After connecting to the correct instance, everything worked as expected!

Issues with Grails 3 domain class named "Application"

I have a legacy system that I am migrating to Grails 3 but I'm running into a naming convention issue. One of our tables is called Application but that is also the name of the Groovy class that runs the application. There seems to be an issue where GORM is confusing the 2 classes and giving type-casting errors. I have tried explicitly casting my Application class in my ApplicationDegree class to try and force GORM to recognize which class I am trying to use but no success.
I know an option is that I can rename my domain Application class to something else and manually map it to the appropriate database table but I want to avoid that as I foresee issues down the road.
So, other than renaming my Domain classes, how can I get Grails/GORM to make the correct mapping.
Grails 3.1.4
Code:
ApplicationDegree ad = ApplicationDegree.findById(10);
Class:
class ApplicationDegree {
Boolean isPrimary
domain.package.Application application
Degree degree
static hasMany = [applicationDegreeMajors: ApplicationDegreeMajor,
applicationDegreeMinors: ApplicationDegreeMinor]
static belongsTo = [domain.package.Application, Degree]
static mapping = {
version false
degree column: 'degree_code'
isPrimary column: 'isPrimary'
}
}
StackTrace:
ERROR org.grails.spring.beans.factory.OptimizedAutowireCapableBeanFactory - Bean couldn't be autowired using grails optimization: Property 'application' threw exception; nested exception is java.lang.IllegalArgumentException: argument type mismatch
ERROR org.grails.spring.beans.factory.OptimizedAutowireCapableBeanFactory - Retrying using spring autowire
ERROR org.grails.web.errors.GrailsExceptionResolver - IllegalStateException occurred when processing request: [GET] /app4grad_V2/college/applications/
Cannot convert value of type [app4grad.Application] to required type [domain.package.Application] for property 'application': no matching editors or conversion strategy found. Stacktrace follows:
java.lang.reflect.InvocationTargetException: null
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.hibernate.InstantiationException: Could not instantiate entity: : domain.package.ApplicationDegree
at app4grad.college.ApplicationsController$$EPuFyMDe.index(ApplicationsController.groovy:14)
... 3 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
... 4 common frames omitted
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type [app4grad.Application] to required type [domain.package.Application] for property 'application'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [app4grad.Application] to required type [domain.package.Application] for property 'application': no matching editors or conversion strategy found
... 4 common frames omitted
Caused by: java.lang.IllegalStateException: Cannot convert value of type [app4grad.Application] to required type [domain.package.Application] for property 'application': no matching editors or conversion strategy found
... 4 common frames omitted
I had the same problem, the problem is that you're using a reserved name : https://grails.org/wiki/Reserved%20Names
Using Intelij Idea you can easily rename you're domain class and the IDE will do the rest for you.

Convert org.apache.tomcat.jdbc.pool.DataSource to org.apache.commons.dbcp.BasicDataSource

Upgrading from Grails 2.2.1 to 2.4.3 everything else has upgraded fine, but having an issue with the Tomcat upgrade to 7.0.54 I am getting an error of
Error initializing the application: Error creating bean with name
'dataSourceMBean': Unsatisfied dependency expressed through
constructor argument with index 0 of type
[org.apache.commons.dbcp.BasicDataSource]: Could not convert
constructor argument value of type
[org.apache.tomcat.jdbc.pool.DataSource] to required type
[org.apache.commons.dbcp.BasicDataSource]: Failed to convert value of
type 'org.apache.tomcat.jdbc.pool.DataSource' to required type
'org.apache.commons.dbcp.BasicDataSource'; nested exception is
java.lang.IllegalStateException: Cannot convert value of type
[org.apache.tomcat.jdbc.pool.DataSource] to required type
[org.apache.commons.dbcp.BasicDataSource]: no matching editors or
conversion strategy found
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'dataSourceMBean': Unsatisfied
dependency expressed through constructor argument with index 0 of type
[org.apache.commons.dbcp.BasicDataSource]: Could not convert
constructor argument value of type
[org.apache.tomcat.jdbc.pool.DataSource] to required type
[org.apache.commons.dbcp.BasicDataSource]: Failed to convert value of
type 'org.apache.tomcat.jdbc.pool.DataSource' to required type
'org.apache.commons.dbcp.BasicDataSource'; nested exception is
java.lang.IllegalStateException: Cannot convert value of type
[org.apache.tomcat.jdbc.pool.DataSource] to required type
[org.apache.commons.dbcp.BasicDataSource]: no matching editors or
conversion strategy found
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:722)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1114)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1017)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.codehaus.groovy.grails.commons.spring.DefaultRuntimeSpringConfiguration.getApplicationContext(DefaultRuntimeSpringConfiguration.java:156)
at org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator.initializeContext(GrailsRuntimeConfigurator.java:188)
at org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator.configure(GrailsRuntimeConfigurator.java:168)
at org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator.configure(GrailsRuntimeConfigurator.java:127)
at org.codehaus.groovy.grails.web.context.GrailsConfigUtils.configureWebApplicationContext(GrailsConfigUtils.java:126)
at org.codehaus.groovy.grails.web.context.GrailsContextLoaderListener.initWebApplicationContext(GrailsContextLoaderListener.java:109)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
The area that I am getting the error in has been around for a while
dataSourceMBean(com.item.management.DataSourceMBean, ref('dataSourceUnproxied'))
The class is:
class DataSourceMBean {
private BasicDataSource dataSource
public DataSourceMBean(BasicDataSource dataSource) {
this.dataSource = dataSource
}
When I change the dataSource to to a specific type :
private org.apache.tomcat.jdbc.pool.DataSource dataSource
Everything compiles and all tests run fine.
Asking when did this change?
Is there an alternative to the BasicDataSource I should be using instead?
I found this article but, not sure if applies
java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.BasicDataSource cannot be cast to org.apache.tomcat.jdbc.pool.DataSource
Unless you really need it to be a BasicDataSource (and I can't see why you would), don't change it to a more specific class, change it to the interface, javax.sql.DataSource. If you do need a particular implementation class, you can define your own dataSource bean by registering a org.apache.commons.dbcp.BasicDataSource in resources.groovy and setting whatever properties are needed, e.g.
import org.apache.commons.dbcp.BasicDataSource
beans = {
dataSourceUnproxied(BasicDataSource) {
driverClassName = 'foo'
username = 'bar'
password = 'secret'
url = 'the_url'
...
}
...
}
You can do this with any bean registered by Grails or a plugin as long as you use the same bean name.

Changing grails "no conversion strategy" error that is not in message.properties

Is there a way to change Grails conversion mismatch error to custom message?
I am getting:
Failed to convert property value of type java.lang.String to required
type java.util.Map for property items;nested exception is
java.lang.IllegalStateException: Cannot convert value of type
[java.lang.String] to required type [java.util.Map] for property
items: no matching editors or conversion strategy found
This error type is not in messages.properties. I am getting this if a user tries to inject request parameter which is not a map into my Command Object, they shouldn't be doing this, but that besides the point:
class CartCommand implements Serializable {
Map<Integer, Integer> items =
MapUtils.lazyMap([:], FactoryUtils.constantFactory(''))
}
Thanks
Use the following key in your message.properties:
cartCommand.items.typeMismatch.map

Resources