将 grails 与类似于以下的域类层次结构一起使用时:
abstract class Vehicle { ... }
class Car extends Vehicle { ... }
class Motorcycle extends Vehicle { ... }
和如下服务:
class VehicleService {
def startRepairing(Car car) { ... }
def startRepairing(Motorcycle motorcycle) { ... }
}
我们在生产中经常遇到如下错误:
No signature of method: VehicleService.startRepairing() is applicable for argument types: (Car_$$_javassist_156) values: [Id: 42343, Class: Car]. Possible solutions: startRepairing(Car)
我们认为发生这种情况是因为我们从集合中检索了 Vehicle 实例,例如 static hasMany = [vehicles: Vehicle],这导致代理实现抽象类Vehicle 但不是具体类(Car、Motorcycle 等)。
我们过去常常从方法中删除参数类型作为解决方案,但我们更愿意拥有它 - 代码更简洁,方法重载是可能的,对 IDE 更友好...
我们想到的一个解决方案是在类型不匹配任何其他方法时使用臭名昭著的 GrailsHibernateUtil.unwrapIfProxy:
class VehicleService {
def startRepairing(Vehicle vehicle) {
startRepairing(GrailsHibernateUtil.unwrapIfProxy(vehicle))
}
def startRepairing(Car car) {
/* actual business logic here */
}
def startRepairing(Motorcycle motorcycle) {
/* actual business logic here */
}
}
但接下来的问题是,我们如何测试它?在开发中运行代码时,我们很少发现 javassist 问题,甚至在生产中它似乎也是“随机”发生的(或者更准确地说,由于我们不知道的情况:)。
是否可以强制实例成为 javassist 代理?一般来说,解决这类问题的好策略是什么?
最佳答案
当您需要延迟加载的类实例时,Hibernate 会创建代理。您需要的东西是预期类的实例或子类,并且一旦完全加载,它基本上就像一个急切加载的实例一样。 Hibernate 使用字节码库创建类的子类以用作代理的方法效果很好。
因此对于 1-1 和一对多的“一方”,延迟加载的实例将是一个代理。同样在“额外惰性”的惰性加载集合中,实例都将是代理。当您知道您只需要来自某些集合的数据时,这种方法会更好 - 在需要按需加载时“填充”集合,查询仅查找 id,并且集合中的实例将是代理仅存储 id。如果你循环遍历整个集合,你最终会运行它的 N+1 个查询,但如果你只需要几个,那么一般来说,它应该比在收集时为所有实例加载所有数据占用更少的资源填充,并在只需要一些时创建非代理集合成员。
另一个容易看到代理的地方是 load() 方法。 get() 在第一个和第二个(如果为域类激活并启用)中查找先前加载的值,否则立即转到数据库,如果没有该 ID 的记录则返回 null。它不会抛出异常,因为很容易知道它是否成功。 load() 但是,如果您访问 id 以外的属性,则只会访问数据库。如果没有记录,则会抛出异常,因为您不一定接近(时间方面或代码方面)创建代理的初始 load() 调用,也因为存在隐式假设通过延迟加载,您期待一个结果,因此在这种情况下 null 是异常(exception)。
关于java - Grails:模拟 hibernate 代理进行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27399533/
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
这是一道面试题,我没有答对,但还是很好奇怎么解。你有N个人的大家庭,分别是1,2,3,...,N岁。你想给你的大家庭拍张照片。所有的家庭成员都排成一排。“我是家里的friend,建议家庭成员安排如下:”1岁的家庭成员坐在这一排的最左边。每两个坐在一起的家庭成员的年龄相差不得超过2岁。输入:整数N,1≤N≤55。输出:摄影师可以拍摄的照片数量。示例->输入:4,输出:4符合条件的数组:[1,2,3,4][1,2,4,3][1,3,2,4][1,3,4,2]另一个例子:输入:5输出:6符合条件的数组:[1,2,3,4,5][1,2,3,5,4][1,2,4,3,5][1,2,4,5,3][
我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test