考虑这种情况。
有地 block ,有的是住宅地 block ,有的是商业地 block 。
也有业主。但是业主只能购买一 block 地 block ,它可以是住宅或商业。
所以,这是我的代码。
@Entity
@Table(name = "PLOT")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Plot {
private int id;
private String number;
private List<Owner> owners = new ArrayList<>();
// getters and setters...
}
@Entity
@Table(name = "RESIDENTIAL_PLOT")
@PrimaryKeyJoinColumn(name = "PLOT_ID")
public class ResidentialPlot extends Plot {
// Some fields
}
@Entity
@Table(name = "COMMERCIAL_PLOT")
@PrimaryKeyJoinColumn(name = "PLOT_ID")
public class CommercialPlot extends Plot {
// Some fields
}
@Entity
@Table(name = "OWNER")
public class Owner {
private int id;
private String name;
private Plot plot;
// getters and setters
}
一切正常,但是当我调用 owner.getPlot() 时
我期待 ResidentialPlot 或 CommercialPlot 实例
因此,我可以通过使用 instanceof 运算符来应用适当的操作。
但它不满足这两个条件!
我做错了什么?
最佳答案
您没有使用多态性,它在 JPA 环境中的危害更大。
您观察到此行为的原因是 Hibernate 使用了代理。当 Hibernate 加载所有者时,它无法判断该地 block 是商业地 block 还是住宅地 block 。它必须做一个额外的查询才能知道它。因此它使用惰性代理初始化绘图字段,该代理是扩展 Plot 的动态生成类的实例,但既不是 CommercialPlot 也不是 ResidentialPlot。
当在代理上调用方法时,代理通过从数据库中获取 Plot 数据来初始化自身,并将其委托(delegate)给 CommercialPlot 或 ResidentialPlot 的实例。
解决方案是使用多态性。向 Plot 类添加一个抽象方法(例如 getType() 或 isResidential()),并在两个子类中实现它。如果这是不可能的,因为您需要依赖于实体类型但不应在实体本身中的业务逻辑,请使用访问者模式。
我写了a blog article关于这个主题,如果您需要更多详细信息,但它是法语的。或许 Google 翻译可以帮助您。
关于java - Hibernate 继承 - 获取父类(super class)实例并转换为子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20093466/
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案
下面例子中的Nested和Child有什么区别?是否只是同一事物的不同语法?classParentclassNested...endendclassChild 最佳答案 不,它们是不同的。嵌套:Computer之外的“Processor”类只能作为Computer::Processor访问。嵌套为内部类(namespace)提供上下文。对于ruby解释器Computer和Computer::Processor只是两个独立的类。classComputerclassProcessor#Tocreateanobjectforthisc
我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我