有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Hibernate@OneToOne与超类,仅在连接时检索超类字段

我已经使用InheritanceType在Hibernate中映射了我的继承层次结构。单个_表和鉴别器列,用于区分不同的实体。超类的所有子类都将其字段存储到辅助表中。例如:

@MappedSuperclass
public abstract class Base
{
   @Id 
   private String id;

   @Version
   private long version;
}

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING) 
public class Parent extends Base
{
    @Column(nullable=false)
    private BigDecimal value;
}

@Entity
@DiscriminatorValue("child1")
@SecondaryTable(name = "Child1")
public class Child1 extends Parent
{
     @Column(table="Child1")
     private String name;
}

@Entity
@DiscriminatorValue("child2")
@SecondaryTable(name = "Child2")
public class Child2 extends Parent
{
     @Column(table="Child2")
     private String name2;
} 

我现在有了一个与父类有@OneToOne关系的实体。此实体只需要使用父类中的值字段。它永远不需要处理父类的任何子类中的任何字段

@Entity
public class AnotherEntity extends Base
{
    @JoinColumn(name="parentId")
    @OneToOne(fetch=FetchType.Lazy, optional=true, targetEntity=Parent.class)
    private Parent parent;
 }

我希望发生的是,只有父字段。从数据库加载与父对象的关系时,将选择类。我看到的是Hibernate试图加载扩展父对象的实体的所有属性。它还左键联接所有辅助表。这是有问题的,因为我有30个扩展父级的实体。这使得获取父实体变得不可行,因为查询执行30次联接

例如,这就是我看到的查询类型:

Hibernate: 
select
    parent.id as id3_0_,
    parent_.version as version3_0_,
    parent.name1 as name110_3_0_,
    parent.name2 as name24_3_0_,
    parent.type as type3_0_ 
from
    Parent parent0_ 
left outer join
    Child1 parent0_2_ 
        on parent0_.id=parent0_2_.id 
left outer join
    Child2 parent0_3_ 
        on parent0_.id=parent0_3_.id 

我不明白为什么Hibernate决定选择父类的子类中定义的所有属性的超集并连接所有的辅助表?我可以理解它加入由被引用父对象的鉴别器值定义的实体的二级表,但否则我会感到困惑

我的问题是,当我在另一个实体类中检索父关系时,如何实现只加载父类中的字段的要求

谢谢


共 (1) 个答案

  1. # 1 楼答案

    辅助表通常用于将单个实体的内容映射到两个表。它不允许使用标准JPA注释进行延迟/选择抓取。您可以使用专有的Hibernate注释,使用单独的select加载它,但只有在必要时。见http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#mapping-declaration-join

    fetch: If set to JOIN, the default, Hibernate will use an inner join to retrieve a secondary table defined by a class or its superclasses and an outer join for a secondary table defined by a subclass. If set to SELECT then Hibernate will use a sequential select for a secondary table defined on a subclass, which will be issued only if a row turns out to represent an instance of the subclass. Inner joins will still be used to retrieve a secondary defined by the class and its superclasses.

    因此,将Hibernate @Table注释的fetch属性设置为SELECT将实现您想要的功能:将发出一个额外的select子句,从适当的辅助表中选择值

    如果您想要延迟抓取,那么辅助表就不是您想要的。你必须使用关联