Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA/Hibernate:@ManyToOne和@OneToOne关系标记为FetchType.LAZY和optional=false未在em.find()上延迟加载?_Java_Hibernate_Jpa_Lazy Loading_Relationships - Fatal编程技术网

Java JPA/Hibernate:@ManyToOne和@OneToOne关系标记为FetchType.LAZY和optional=false未在em.find()上延迟加载?

Java JPA/Hibernate:@ManyToOne和@OneToOne关系标记为FetchType.LAZY和optional=false未在em.find()上延迟加载?,java,hibernate,jpa,lazy-loading,relationships,Java,Hibernate,Jpa,Lazy Loading,Relationships,我有以下实体(仅显示相关映射): 请注意上面的注释:与其他实体之间有三种@XToOne关系: 用户(一个简单ID为PK的SecurityIdentity子类,由代表所有者的PQ引用): 投标: @Entity @Table(name = "Tenderings") public class Tendering implements Serializable { @Id @Column(name = "pq_id", insertable = false, updatable =

我有以下实体(仅显示相关映射):

请注意上面的注释:与其他实体之间有三种
@XToOne
关系:

用户(一个简单ID为PK的SecurityIdentity子类,由代表所有者的PQ引用):

投标

@Entity
@Table(name = "Tenderings")
public class Tendering implements Serializable
{
    @Id
    @Column(name = "pq_id", insertable = false, updatable = false)
    private Integer pqId;

    @Column(name = "external_code")
    private String externalCode;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "pq_id", referencedColumnName = "id")
    private PQ pq;

    ...
}
不要对共享ID的组和用户感到困惑,只需将它们视为简单的ID即可。投标只是一个单独的文件对象(一对一)

如您所见,PQ实体上有三个
@XToOne
关系,如果未设置获取类型,则会立即加载(JPA默认)。为了防止这种情况,我将所有
@XToOne
关系标记为
FetchType.LAZY

现在使用

em.find(PQ.class,someExistingId)

我得到Hibernate输出:

23:53:55,815 INFO  [stdout] Hibernate: select pq0_.id as id291_0_, pq0_.description as descript2_291_0_, pq0_.name as name291_0_, pq0_.submission_date as submission4_291_0_, pq0_.user_id as user5_291_0_ from PQs pq0_ where pq0_.id=?
23:53:55,818 INFO  [stdout] Hibernate: select user0_.id as id280_0_, user0_1_.identity_type_id as identity2_280_0_, user0_.is_enabled as is1_297_0_, user0_.name as name297_0_, user0_.password as password297_0_, user0_.person_id as person5_297_0_ from Users user0_ inner join SecurityIdentities user0_1_ on user0_.id=user0_1_.id where user0_.person_id=?
23:53:55,821 INFO  [stdout] Hibernate: select group0_.id as id280_0_, group0_1_.identity_type_id as identity2_280_0_, group0_.pq_id as pq2_281_0_ from Groups group0_ inner join SecurityIdentities group0_1_ on group0_.id=group0_1_.id where group0_.pq_id=?
23:53:55,823 INFO  [stdout] Hibernate: select tendering0_.pq_id as pq1_296_0_, tendering0_.binary_file as binary2_296_0_, tendering0_.customer_id as customer6_296_0_, tendering0_.description as descript3_296_0_, tendering0_.external_code as external4_296_0_, tendering0_.title as title296_0_ from Tenderings tendering0_ where tendering0_.pq_id=?
00:47:34,397 INFO  [stdout] Hibernate: select pq0_.id as id361_0_, pq0_.description as descript2_361_0_, pq0_.name as name361_0_, pq0_.submission_date as submission4_361_0_, pq0_.user_id as user5_361_0_ from PQs pq0_ where pq0_.id=?
00:47:34,410 INFO  [stdout] Hibernate: select user0_.id as id350_0_, user0_1_.identity_type_id as identity2_350_0_, user0_.is_enabled as is1_367_0_, user0_.name as name367_0_, user0_.password as password367_0_, user0_.person_id as person5_367_0_ from Users user0_ inner join SecurityIdentities user0_1_ on user0_.id=user0_1_.id where user0_.person_id=?
00:47:34,413 INFO  [stdout] Hibernate: select group0_.id as id350_0_, group0_1_.identity_type_id as identity2_350_0_, group0_.pq_id as pq2_351_0_ from Groups group0_ inner join SecurityIdentities group0_1_ on group0_.id=group0_1_.id where group0_.pq_id=?
这三个额外的选择源于@XToOne关系(如网上许多地方所述)。我主要关注的来源是:

如前所述,不应获取
@manytone
关系
用户

@ManyToOne(fetch=FetchType.LAZY)
应该可以正常工作

。。。这里是从PQUser的关系,但是是从
select user0.id as id280\u 0\u>语句中可以看到的,
获取的

对于其他两个
组组
招标
,这两个
@OneToOne
反向映射,外键引用PQs表的PK(ID),从而在PQ实体中产生相同的映射

请注意,所有三种关系都不是可选的:PQ始终有所有者(用户),并且PQ始终由招标和集团实体引用。我只是还没有在上面的JPA中建模

因此,将
optional=false
添加到PQ实体的三个关系时:

@Entity
@Table(name = "PQs")
public class PQ implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    private Integer id;

    @Column
    private String name;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "user_id", referencedColumnName = "person_id")
    private User user;

    @OneToOne(mappedBy = "pq", fetch = FetchType.LAZY, optional = false)
    private Group group;

    @OneToOne(mappedBy = "pq", fetch = FetchType.LAZY, optional = false)
    private Tendering tendering;

    ...
}
。。。我得到以下Hibernate输出:

23:53:55,815 INFO  [stdout] Hibernate: select pq0_.id as id291_0_, pq0_.description as descript2_291_0_, pq0_.name as name291_0_, pq0_.submission_date as submission4_291_0_, pq0_.user_id as user5_291_0_ from PQs pq0_ where pq0_.id=?
23:53:55,818 INFO  [stdout] Hibernate: select user0_.id as id280_0_, user0_1_.identity_type_id as identity2_280_0_, user0_.is_enabled as is1_297_0_, user0_.name as name297_0_, user0_.password as password297_0_, user0_.person_id as person5_297_0_ from Users user0_ inner join SecurityIdentities user0_1_ on user0_.id=user0_1_.id where user0_.person_id=?
23:53:55,821 INFO  [stdout] Hibernate: select group0_.id as id280_0_, group0_1_.identity_type_id as identity2_280_0_, group0_.pq_id as pq2_281_0_ from Groups group0_ inner join SecurityIdentities group0_1_ on group0_.id=group0_1_.id where group0_.pq_id=?
23:53:55,823 INFO  [stdout] Hibernate: select tendering0_.pq_id as pq1_296_0_, tendering0_.binary_file as binary2_296_0_, tendering0_.customer_id as customer6_296_0_, tendering0_.description as descript3_296_0_, tendering0_.external_code as external4_296_0_, tendering0_.title as title296_0_ from Tenderings tendering0_ where tendering0_.pq_id=?
00:47:34,397 INFO  [stdout] Hibernate: select pq0_.id as id361_0_, pq0_.description as descript2_361_0_, pq0_.name as name361_0_, pq0_.submission_date as submission4_361_0_, pq0_.user_id as user5_361_0_ from PQs pq0_ where pq0_.id=?
00:47:34,410 INFO  [stdout] Hibernate: select user0_.id as id350_0_, user0_1_.identity_type_id as identity2_350_0_, user0_.is_enabled as is1_367_0_, user0_.name as name367_0_, user0_.password as password367_0_, user0_.person_id as person5_367_0_ from Users user0_ inner join SecurityIdentities user0_1_ on user0_.id=user0_1_.id where user0_.person_id=?
00:47:34,413 INFO  [stdout] Hibernate: select group0_.id as id350_0_, group0_1_.identity_type_id as identity2_350_0_, group0_.pq_id as pq2_351_0_ from Groups group0_ inner join SecurityIdentities group0_1_ on group0_.id=group0_1_.id where group0_.pq_id=?
请注意,我只在PQ实体上使用了
optional=false
,因为这是我在
em.find(…)
中使用的。(如果这还不够,请告诉我。)

我现在的问题有两个:

  • 为什么对
    用户
    实体的
    @ManyToOne
    会被急切地获取(鉴于据说该实体工作很懒散,请参见)
  • 为什么只有
    OneToOne
    招标
    实体的关系没有被提取?是因为
    招标
    实体将PQ的PK列引用为PK本身(
    招标
    中的
    @Id
    ),而
    集团
    实体没有引用PK(与PQ的PK有规则关系)
  • 怎么了?如何使这些非可选关系变得懒惰?(没有代码插入或其他黑客,只有简单的注释…)

    我知道LAZY只是一个提示,让JPA提供者做一些关于延迟加载的事情,或者不做,但是在这种情况下,似乎有其他事情是错误的(作为它工作的一部分)


    PS:我使用的是Hibernate 4.0 BETA版,JBoss 7.0.0.Final附带的版本,只提供JPA注释(以上都是JPA 1.0兼容的)。

    嗨,我不确定JPA,但是对于
    多对一
    一对一
    映射,Hibernate支持的惰性值是
    代理
    无代理
    false
    默认为false。检查DTD的这一部分

    lazy=“proxy |无代理| false”


    你可以检查一下。我认为这在一定程度上回答了您的第一个问题。

    *ToOne关系意味着在对象初始化之后必须有(代理)bean,一旦以任何方式访问它,它将触发select(您正在看到它),您确定您对可能强制加载的对象不做任何操作吗

    使用hibernate注释和jpa注释之间存在差异,据我所知,hibernate默认情况下是延迟加载的,但在某些情况下除外。下面是一个简短的讨论:


    您好,您显示了额外的选择,因为它将对所有涉及的实体执行选择,请尝试使用FetchType.LAZY作为默认的一对多,在大多数情况下,使用FETCH JOIN来获得结果

    我希望能帮助您或需要此信息的人

    默认的
    lazy=“proxy | no proxy | false”
    是代理,正如您发布的链接(参见12):“lazy(可选-默认为代理):默认情况下,单点关联是代理的。lazy=“no proxy”“指定在首次访问实例变量时应延迟获取属性。这需要构建时字节码检测。lazy=“false”指定关联将始终被急切地获取。“可能这只是一个bug。请参阅,这是类似的。
    00:47:34,397 INFO  [stdout] Hibernate: select pq0_.id as id361_0_, pq0_.description as descript2_361_0_, pq0_.name as name361_0_, pq0_.submission_date as submission4_361_0_, pq0_.user_id as user5_361_0_ from PQs pq0_ where pq0_.id=?
    00:47:34,410 INFO  [stdout] Hibernate: select user0_.id as id350_0_, user0_1_.identity_type_id as identity2_350_0_, user0_.is_enabled as is1_367_0_, user0_.name as name367_0_, user0_.password as password367_0_, user0_.person_id as person5_367_0_ from Users user0_ inner join SecurityIdentities user0_1_ on user0_.id=user0_1_.id where user0_.person_id=?
    00:47:34,413 INFO  [stdout] Hibernate: select group0_.id as id350_0_, group0_1_.identity_type_id as identity2_350_0_, group0_.pq_id as pq2_351_0_ from Groups group0_ inner join SecurityIdentities group0_1_ on group0_.id=group0_1_.id where group0_.pq_id=?