我正在尝试这样做,但我得到了错误.
"具有相同标识符值的不同对象已与会话关联"
看起来我需要从hibernate会话中删除dbObject.
def object = messageParserService.parseMessage(messageType, messageText)
def dbObject = object.getClass().findByIdentifier(object.identifier)
if(dbObject != null){
object.id = dbObject.id
object.dateCreated = dbObject.dateCreated
}
if(!object.save()) {
object.errors.each {println it}
}
Run Code Online (Sandbox Code Playgroud) 正如我在另一个问题的答案中注意到的那样,在GORM中测试finder方法时会遇到一些问题.
我想从中获取所有对象Something并支持排序和分页,所以我写了这个:
SomethingListVO findAllSomethings(int offset = 0, int limit = 50) {
def somethingCount = Something.count()
def somethings = Something.findAll([max: limit,
offset:offset,
sort: "number",
order: "asc"])
return new SomethingListVO(somethingCount,somethings)
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为如果要添加分页或排序等内容,则需要查询.但是如果你添加一个查询,SELECT * FROM Something你的测试就会失败.
有没有办法测试这种方法(分页/排序)?
这种方法似乎提供了更多功能,但它不适用于我的grails安装.
我有以下域类:
class User {
static hasMany = [roles:String]
}
Run Code Online (Sandbox Code Playgroud)
我想找到每个有角色的用户ROLE_ADMIN.有没有可能用动态查找器做到这一点?user.findAllByRoles('ROLE_ADMIN')似乎给了我一个错误.
UPDATE:这是很容易查询的关联,其中类A具有类的列表B实例和两A和B的域类.但是这里的类A是一个域类,类B是一个简单的Java字符串.
查询包含其他域对象列表的关联的代码如下所示:
`User.findAll { roles { role_name=='ROLE_ADMIN' } }`
Run Code Online (Sandbox Code Playgroud)
我正在寻找的是一种指定String值的方法,例如:
`User.findAll { roles {THIS_VALUE=='ROLE_ADMIN' }}`
Run Code Online (Sandbox Code Playgroud)
更新2:据我所知,不可能使用具有原始类型集合的标准.但是可以使用HQL:
User.findAll("from User a where :roles in elements(roles)",[roles:'ROLE_ADMIN'])
Run Code Online (Sandbox Code Playgroud)
但是,它不像查询findAll或where查询那样有用.我不能链接findAll方法,所以定义其他方法,例如:获取ROLE_ADMIN用户名像'xxx'的用户需要重写整个HQL查询.也许有可能以表达的HQL形式表达上述条件where?
在属性上使用投影时,结果将作为列表返回,其中元素的顺序与投影块中定义的顺序相同.同时,列表中缺少属性名称,这对开发人员来说确实是不利的,因为结果将被传递,并且调用者需要知道哪个值属于哪个属性.有没有办法从Criteria查询返回一个带有属性名称作为值的键的映射?
所以,以下代码:
def c = Trade.createCriteria()
def remicTrades = c.list {
projections {
property('title', 'title')
property('author.name', 'author')
}
def now = new Date()
between('publishedDate', now-365, now)
}
Run Code Online (Sandbox Code Playgroud)
返回:
[['book1', 'author1']['book2', 'author2']]
Run Code Online (Sandbox Code Playgroud)
相反,我希望它返回:
[[book:'book1', author:'author1'][book:'book2', author:'author2']]
Run Code Online (Sandbox Code Playgroud)
我知道我可以在得到结果之后安排这种方式,但我认真地认为标准应该使用属性别名来返回模仿SQL查询结果的地图列表,而不是一个平淡无奇的列表.
对于以下域模型:
class Route {
String name
static hasMany = [checkPoints:CheckPoint]
static belongsTo = [someBigObject:SomeBigObject]
static mapping = {
checkPoints lazy: false
}
}
Run Code Online (Sandbox Code Playgroud)
我需要Route从Web服务返回一个特定的JSON.我希望这个JSON包含所有checkPoints但没有其他组合(即:) someBigObject.
如果我做
def route = Route.findById(id)
render route as JSON
Run Code Online (Sandbox Code Playgroud)
我得到的只是id的checkPoints,没有其他字段被提取:
{
"class": "com.example.Route",
"id": 1,
"checkPoints": [
{
"class": "CheckPoint",
"id": 1
},
{
"class": "CheckPoint",
"id": 2
},
{
"class": "CheckPoint",
"id": 4
},
{
"class": "CheckPoint",
"id": 3
}
],
"someBigObject": {
"class": "SomeBigObject",
"id": 2 …Run Code Online (Sandbox Code Playgroud) 我在我的域中使用已分配的ID
class Book {
Integer id
String name
static mapping = {
id generator: 'assigned'
}
}
Run Code Online (Sandbox Code Playgroud)
所以要添加一本新书:
def book = new Book([name: "The Adventures of Huckleberry Finn"])
book.id = 123
book.save(flush: true)
Run Code Online (Sandbox Code Playgroud)
一切都很完美,问题出在我的单元测试中
首先我只能嘲笑1域类,其次,我不能在单元测试使用.save(),所以我唯一的选择(据我所知)是使用mockDomain如下:
mockDomain(Book, [ [id: 123, name: "The Adventures of Huckleberry Finn"] ])
Run Code Online (Sandbox Code Playgroud)
但它不起作用,它将在没有"id generator:'assigned'"的普通域中工作
有任何想法吗?我读到在集成测试中我不会遇到这个问题,这只是单元测试中的问题谢谢
当我在域类中映射自定义标识属性时,为什么hibernate会检查唯一约束?当我更新对象时,尽管发布的字段值与存储在DB中的值相同,但验证失败!即使我没有对表单进行任何更改(确保dirty:false并且没有属性绑定错误),也会发生这种情况.我有一个Grails域类,如下所示:
class User {
Long profileId
String email
String username
String password
String title
String firstname
String lastname
String zipCode
Date lastLoginDate
static constraints = {
profileId nullable: true, blank: true
email blank: false, unique: true, email: true
username blank: false, unique: true
password blank: false
lastLoginDate nullable: true
firstname nullable: true
lastname nullable: true
zipCode nullable: true
}
static mapping = {
table 'USER_PROFILE'
id name:"profileId", column: "profile_id", generator: "sequence", params: [sequence:'userprofile_sequence']
version false
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当我创建具有最小属性集的用户时,会创建一条记录.但是当我尝试更新相同的对象时:def user = …
当我将实例保存为:
test.save()
Run Code Online (Sandbox Code Playgroud)
保存可能会失败.我可以
if (!test.save(flush:true) {
// save failed
}
Run Code Online (Sandbox Code Playgroud)
考虑一下我从另一个函数获取实例并且无法执行此检查的情况,因为我不会再次保存实例.
有没有办法检查实例是否仍然存在于数据库中还是具有未保存状态?
在Grails 2.4.4下,我们使用了用作域对象包装器的类.
它们看起来像这样:
class Foo {
@Delegate
OurDomainClass ourDomainClass
...
}
Run Code Online (Sandbox Code Playgroud)
这很有效,但是当尝试在Grails 3.0.11下编译时,我们得到了这个:
Foo.groovy:14:在非抽象类中不能有抽象方法.必须将类'Foo'声明为abstract或者必须实现方法'org.springframework.validation.Errors org_grails_datastore_gorm_GormValidateable__errors $ get()'.@第14行,第1列.coo Foo {^
删除@Delegate注释将使编译通过,但是对基础类的方法的调用显然不起作用.
有没有办法解决这个问题或实现相同的行为并让它通过Grails 3下的编译?
这比任何事情都更令人烦恼,但任何人都可以解释为什么IntelliJ(在我的情况下为15)无法找到whereDomain对象的方法?我可以使用动态查找器完成,但where方法永远不会完成.
在下面的图像中,您可以看到IntelliJ对findBy*感到满意,但不知道在哪里.尝试自动填充方法名称时也是如此.
调试等工作正常,所以它在内部以某种方式工作.
grails ×10
grails-orm ×10
groovy ×2
findall ×1
grails-3.0 ×1
hibernate ×1
json ×1
pagination ×1
unit-testing ×1
validation ×1