Hibernate 在命名查询中替换实体名称

Hibernate 在命名查询中替换实体名称,hibernate,named-query,Hibernate,Named Query,这是一个场景: 我有两个用hibernate映射的类:“Foo”和“EnhancedFoo” 两个类都映射到同一个表“foo” EnhancedFoo扩展了Foo Foo.hbm.xml包含一个命名查询“find active foos”,如下所示: from Foo foo where foo.active = true 现在,如果我尝试加载配置,会出现以下异常: could not resolve property: active of: EnhancedFoo [

这是一个场景:

  • 我有两个用hibernate映射的类:“Foo”和“EnhancedFoo”

  • 两个类都映射到同一个表“foo”

  • EnhancedFoo扩展了Foo

  • Foo.hbm.xml包含一个命名查询“find active foos”,如下所示:

     from Foo foo where foo.active = true
    
现在,如果我尝试加载配置,会出现以下异常:

could not resolve property: active of: EnhancedFoo [
    from EnhancedFoo foo where foo.active = true
]
这是正确的,因为在EnhancedFoo.hbm.xml中没有映射属性“active”,但为什么hibernate要用“EnhancedFoo”替换“Foo”


这就是我尝试过的:

尝试在映射文件上添加“enity name”属性,如下所示:

<class name="myproject.data.entity.Foo" table="foo" entity-name="Foo">
.......
<class name="myproject.data.entity.EnhancedFoo" table="foo" entity-name="EnhancedFoo">

以下是代码的相关部分:

//Foo.java
public class Foo 
{
  private long id;
  private boolean active;

  // getters and setters
}


//EnhancedFoo.java
public class EnhancedFoo extends Foo
{
  private String extraProperty

  // getter and setter
}

//Foo.hbm.xml
//.....
<class name="myproject.data.entity.Foo" table="foo" entity-name="Foo">
  <id column="id" name="id">
    <generator class="assigned"/>
  </id>

  <property name="active" column="active" />
</class>

<query name="find_active_foos">
  <![CDATA[
    from Foo foo where foo.active = true
  ]]>
</query>


//EnhancedFoo.hbm.xml
//.....
<class name="myproject.data.entity.EnhancedFoo" table="foo" entity-name="EnhancedFoo">
  <id column="id" name="id">
    <generator class="assigned"/>
  </id>
</class>
//Foo.java
公开课Foo
{
私人长id;
私有布尔活动;
//接球手和接球手
}
//EnhancedFoo.java
公共类增强Foo扩展Foo
{
私有字符串外部属性
//接二连三
}
//Foo.hbm.xml
//.....
//EnhancedFoo.hbm.xml
//.....
我发现两个问题:

1) 永远不应该同时映射超类和子类。问题是,子类实例也是超类的实例,在您的示例中,EnhancedFoo实例也是Foo的实例。这会在查看会话缓存时混淆hibernate。(我没有你的问题,但我有这样的效果,当我加载主键值作为条件的超类实例时,uniqueResult()失败了,因为它在缓存中找到了一个超类实例和一个子类。)替换的Foo也可能是类似的效果

如果要继续使用这两个映射,可以这样做

//AbstractFoo.java
public abstract class AbstractFoo 
{
  private long id;
  private boolean active;
  // getters and setters
}

//Foo.java
public class Foo extends AbstractFoo
{  // empty body
}

//EnhancedFoo.java
public class EnhancedFoo extends AbstractFoo
{
  private String extraProperty
  // getter and setter
}
然后让映射文件保持原样

(另一种可能是只映射一个类并处理Java中的差异。)

2) 对于您的插入问题:

您收到了错误消息
Unknown entity:myproyect.data.entity.Foo
,在project中使用了“y”而不是“j”。您是否有打字错误?

将两个实体映射到同一张表上没有多大意义。你为什么要这样做?很抱歉耽搁了,实际上Foo是一个巨大的整体式的无所不能类,团队不想再碰它了,所以我们尝试映射第二个类,只是为了持久性,因为实例化Foo在其构造函数中做了很多幕后工作=(很抱歉,我发布了错误的答案,我们最终应用了您的解决方案,谢谢!
//AbstractFoo.java
public abstract class AbstractFoo 
{
  private long id;
  private boolean active;
  // getters and setters
}

//Foo.java
public class Foo extends AbstractFoo
{  // empty body
}

//EnhancedFoo.java
public class EnhancedFoo extends AbstractFoo
{
  private String extraProperty
  // getter and setter
}