在grails域对象中使用原始属性时出现以下错误:
Null value was assigned to a property of primitive type setter of MyDomain.myAttribute
org.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter of MyDomain.myAttribute
at grails.orm.HibernateCriteriaBuilder.invokeMethod(HibernateCriteriaBuilder.java:1077)
Run Code Online (Sandbox Code Playgroud) 我收到此错误消息:
error:找到对集合的共享引用:Person.relatedPersons
当我试图执行时addToRelatedPersons(anotherPerson):
person.addToRelatedPersons(anotherPerson);
anotherPerson.addToRelatedPersons(person);
anotherPerson.save();
person.save();
Run Code Online (Sandbox Code Playgroud)
我的域名:
Person {
static hasMany = [relatedPersons:Person];
}
Run Code Online (Sandbox Code Playgroud)
知道为什么会这样吗?
使用Grails有几种方法可以做同样的事情.
查找所有域类实例:
Book.findAll()
Book.getAll()
Book.list()
Run Code Online (Sandbox Code Playgroud)
检索指定id的域类的实例:
Book.findById(1)
Book.get(1)
Run Code Online (Sandbox Code Playgroud)
你什么时候使用每一个?性能有显着差异吗?
有没有办法获得由两个字段排序的列表,比如姓和名?
我知道.listOrderByLastAndFirst和.list(sort:'last, first')将无法正常工作.
我正在开发一个RESTful接口,用于为JavaScript应用程序提供JSON数据.
在服务器端,我使用Grails 1.3.7并使用GORM域对象进行持久化.我实现了一个自定义JSON Marshaller来支持编组嵌套域对象
以下是示例域对象:
class SampleDomain {
static mapping = { nest2 cascade: 'all' }
String someString
SampleDomainNested nest2
}
Run Code Online (Sandbox Code Playgroud)
和
class SampleDomainNested {
String someField
}
Run Code Online (Sandbox Code Playgroud)
SampleDomain资源在URL/rs/sample/so/rs/sample/1下发布,指向ID为1的SampleDomain对象
当我使用自定义json marshaller(/ rs/sample/1上的GET)渲染资源时,我得到以下数据:
{
"someString" : "somevalue1",
"nest2" : {
"someField" : "someothervalue"
}
}
Run Code Online (Sandbox Code Playgroud)
这正是我想要的.
现在出现了问题:我尝试通过PUT将相同的数据发送到资源/ rs/sample/1.
要将json数据绑定到域对象,处理请求的控制器调用def domain = SampleDomain.get(id)以及domain.properties = data数据是unmarshalled对象的位置.
"someString"字段的绑定工作得很好,但是嵌套对象没有使用嵌套数据填充,因此我得到一个错误,即属性"nest2"为null,这是不允许的.
我已经尝试过实现一个自定义PropertyEditorSupport以及一个StructuredPropertyEditor并为该类注册编辑器.
奇怪的是,当我提供非嵌套值时,编辑器才会被调用.所以当我通过PUT将以下内容发送到服务器时(这没有任何意义;))
{
"someString" : "somevalue1",
"nest2" : "test"
}
Run Code Online (Sandbox Code Playgroud)
至少会调用属性编辑器.
我查看了代码GrailsDataBinder.我发现通过指定关联的路径而不是提供地图,设置关联的属性似乎有效,因此以下工作原理:
{
"someString" : "somevalue1", …Run Code Online (Sandbox Code Playgroud) 在Grails应用程序中,我了解您通过添加为每个域类启用第二级缓存
static mapping {
cache true
}
Run Code Online (Sandbox Code Playgroud)
默认情况下,第二级缓存仅在get()调用时使用,但也可以通过添加cache true到查询中用于条件查询和动态查找器.
但是,我仍然不确定我是否理解查询缓存的工作原理.我最好的猜测是:
Author.findByName('bob', [cache: true])执行类似查询之前,计算缓存键,该缓存键基于域类(作者),查询(findByName)和查询参数('bob').如果在作者查询缓存中找到该键,则返回缓存的结果而不是执行查询在我们考虑返回Book实例的查询可以加入Author表之前,这似乎是合理的.在这种情况下,在保存,删除或更新作者时,有必要刷新Book和Author查询缓存.这让我怀疑可能只有一个查询缓存,并且只要保存了任何缓存的域类,它就会被清除?
在Grails文档中,它提到了这一点
除了使用Hibernate的二级缓存来缓存实例的能力之外,您还可以缓存对象的集合(关联).
例如:
class Author {
static hasMany = [books: Book]
static mapping = {
cache true // Author uses the 2nd level cache
books cache: true // associated books use the 2nd level cache
}
}
class Book {
static belongsTo = [author: Author]
static mapping = {
cache true // Book uses the 2nd …Run Code Online (Sandbox Code Playgroud) 我有一个奇怪的情况,似乎表明GORM缓存问题
//begin with all book.status's as UNREAD
Book.list().each { book.status = Status.READ ; book.save() }
println (Book.findAllByStatus (Status.READ)) //will print an empty list
println (Book.list().findAll (it.status == Status.READ)) // will print all books
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么最后两个查询会返回不同的结果.
但是,如果我对book.save做了以下修改(flush:true).这两个println语句都将返回所有书籍.
我的印象是,在单个应用程序中这不是必需的.
作为参考,我正在使用
@HoàngLong
我的问题如下所示,假设action1/action2被多次调用,没有特定的模式
def action1 = {
Foo foo = Foo.get(params.id)
//... modify foo
foo.save() //if I flush here, it will be inefficient if action1 is called in sequence
}
def action2 = {
//if I flush …Run Code Online (Sandbox Code Playgroud) 获取与给定GORM域对象关联的持久属性列表的最佳/最简单方法是什么?我可以获取所有属性的列表,但是此列表包含非持久性字段,例如class和constraints.
目前我正在使用它并nonPersistent使用我创建的列表过滤掉属性列表:
def nonPersistent = ["log", "class", "constraints", "properties", "errors", "mapping", "metaClass"]
def newMap = [:]
domainObject.getProperties().each { property ->
if (!nonPersistent.contains(property.key)) {
newMap.put property.key, property.value
}
}
Run Code Online (Sandbox Code Playgroud)
似乎必须有一种更好的方法来获得持久性属性.
我撇了一些Grails文档,发现这一点关于read()Grails的方法.如果我正确理解了这一点,您可以从数据库中提取一个只读对象的"只读"版本,该版本只会在显式save()调用中保存.在我看来,read()只要你有一个你不希望被改变的对象,就应该使用一个调用.
但为什么你不会总是使用read()电话?因为save()无论如何,对象将被更改为读/写权限,仅仅读取对象而不是获取它是不是更安全?
我正在使用带有投影的Criteria来获取我的帐户域中的标签列表.像这样:
def tags = Account.createCriteria().list {
projections { property("tags") }
}
Run Code Online (Sandbox Code Playgroud)
我的帐户域名:
class Account {
static mapWith = "mongo"
List<Tag> tags
...
static embedded = ['tags']
}
Run Code Online (Sandbox Code Playgroud)
BuildConfig.groovy
// using grails 2.3.8
plugins {
runtime ":hibernate:3.6.10.17"
compile ":mongodb:2.0.1"
Run Code Online (Sandbox Code Playgroud)
这一直有效,直到我将Grails的MongoDB GORM插件从2.0.1升级到3.0.1
compile ":mongodb:3.0.1"
Run Code Online (Sandbox Code Playgroud)
现在我看到以下错误......
The class [java.util.List] is not a known persistent type.
at org.grails.datastore.mapping.core.AbstractSession.retrieveAll(AbstractSession.java:723)
at org.grails.datastore.mapping.mongo.query.MongoQuery$AggregatedResultList.initializeFully(MongoQuery.java:1601)
at org.grails.datastore.mapping.mongo.query.MongoQuery$AggregatedResultList.size(MongoQuery.java:1764)
Run Code Online (Sandbox Code Playgroud)
为什么以前工作但现在失败了?我不想重写所有现有的查询来使用mongoDB的聚合框架.
grails ×10
grails-orm ×10
hibernate ×2
caching ×1
data-binding ×1
gorm-mongodb ×1
groovy ×1
java ×1
json ×1
mongodb ×1
read-write ×1
sql-order-by ×1