相关疑难解决方法(0)

使OneToOne关系变得懒惰

在我们正在开发的这个应用程序中,我们注意到一个视图特别慢.我分析了视图并注意到hibernate执行了一个查询,即使数据库中只有两个对象要获取,也需要10秒.所有OneToManyManyToMany关系都是懒惰的,所以这不是问题.在检查正在执行的SQL时,我注意到查询中有超过80个连接.

进一步检查这个问题,我注意到问题是由实体类的深层次结构OneToOneManyToOne关系引起的.所以,我想,我只是让他们变得懒惰,这应该解决问题.但是,无论是标注@OneToOne(fetch=FetchType.LAZY)@ManyToOne(fetch=FetchType.LAZY)似乎不工作.我得到一个异常,或者它们实际上并没有被代理对象替换,因此是懒惰的.

任何想法我将如何让这个工作?请注意,我不使用persistence.xml定义关系或配置细节,一切都在java代码中完成.

java hibernate jpa

203
推荐指数
6
解决办法
10万
查看次数

JPA eager fetch不加入

JPA的获取策略到底控制了什么?我无法发现渴望和懒惰之间的任何区别.在这两种情况下,JPA/Hibernate都不会自动加入多对一关系.

示例:Person有一个地址.地址可以属于很多人.JPA带注释的实体类看起来像:

@Entity
public class Person {
    @Id
    public Integer id;

    public String name;

    @ManyToOne(fetch=FetchType.LAZY or EAGER)
    public Address address;
}

@Entity
public class Address {
    @Id
    public Integer id;

    public String name;
}
Run Code Online (Sandbox Code Playgroud)

如果我使用JPA查询:

select p from Person p where ...
Run Code Online (Sandbox Code Playgroud)

JPA/Hibernate生成一个SQL查询以从Person表中进行选择,然后为每个人选择一个不同的地址查询:

select ... from Person where ...
select ... from Address where id=1
select ... from Address where id=2
select ... from Address where id=3
Run Code Online (Sandbox Code Playgroud)

这对于大型结果集非常糟糕.如果有1000个人,则会生成1001个查询(1个来自Person,1000个来自地址).我知道这是因为我正在查看MySQL的查询日志.我的理解是,将地址的提取类型设置为eager会导致JPA/Hibernate自动使用连接进行查询.但是,无论获取类型如何,它仍会为关系生成不同的查询.

只有当我明确告诉它加入时它才真正加入:

select p, a from Person p left join p.address …
Run Code Online (Sandbox Code Playgroud)

java hibernate jpa join

106
推荐指数
6
解决办法
12万
查看次数

(1 + N)选择OnetoOne关联

考虑以下型号:

@Entity
public class User {

    @Id
    @Column(name = "USER_ID")
    private Long userId;

    @Column(name = "FIRST_NAME")
    private String firstName;

    @Column(name = "LAST_NAME")
    private String lastName;

    @OneToOne
    @PrimaryKeyJoinColumn
    private UserExt userExt;
...     //getters and setters

}

@Entity
public class UserExt {

    @Id
    @Column(name="USER_ID")
    private Long id;

    private String cdpId;

    private Date lastChanged;
...     //getters and setters
}
Run Code Online (Sandbox Code Playgroud)

执行时:

Query query = session.createQuery("from User");
List<User> list = query.list();
Run Code Online (Sandbox Code Playgroud)

Hibernate执行

Hibernate: select user0_.USER_ID as USER1_0_, user0_.FIRST_NAME as FIRST2_0_, user0_.LAST_NAME as LAST3_0_, user0_.EXT_USERNAME as …
Run Code Online (Sandbox Code Playgroud)

java performance orm hibernate one-to-one

13
推荐指数
1
解决办法
5811
查看次数

如何避免1 + n数据库调用Hibernate中的双向可选一对一关联?

拥有以下简化实体:

@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;
}

@Entity
@Table(name = "t_invoice")
public class Invoice extends AbstractEntity {
    @OneToOne(optional = false, fetch = FetchType.EAGER)
    @JoinColumn(name = "order_id")
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    private Order order;
}

@Entity
@Table(name = "t_order")
public class Order extends AbstractEntity {
    @OneToMany(mappedBy = "order", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    @SortNatural
    private SortedSet<OrderLine> orderLines = new TreeSet<>();

    @OneToOne(optional = true, mappedBy = …
Run Code Online (Sandbox Code Playgroud)

hibernate jpa spring-data-jpa

5
推荐指数
1
解决办法
418
查看次数

标签 统计

hibernate ×4

java ×3

jpa ×3

join ×1

one-to-one ×1

orm ×1

performance ×1

spring-data-jpa ×1