相关疑难解决方法(0)

与共享主键的OneToOne关系生成n + 1个选择; 任何解决方法?

想象一下关系数据库中的2个表,例如Person和Billing.在这些实体之间定义了(非强制性)OneToOne关联,并且它们共享Person主键(即PERSON_ID在Person和Billing中定义,并且它是后者中的外键).

通过命名查询对Person进行选择时,例如:

from Person p where p.id = :id
Run Code Online (Sandbox Code Playgroud)

Hibernate/JPA生成两个选择查询,一个在Person表上,另一个在Billing表上.

上面的示例非常简单,并且不会导致任何性能问题,因为查询只返回一个结果.现在,假设PersonnOneToOne关系(均非强制性)与其他实体(所有共享Person主键).

如果我错了,请纠正我,但是select在Person上运行查询,返回r行,将导致(n+1)*rHibernate生成选择,即使这些关联是懒惰的.

是否存在针对此潜在性能灾难的解决方法(除了根本不使用共享主键)?谢谢你的所有想法.

java hibernate jpa

7
推荐指数
1
解决办法
5091
查看次数

JPA+Hibernate...关联不是单个查询,而是执行多个查询进行连接

我有两个名为 Banners 和 BannerGroup 的类。

\n\n

我已经创建了双向关系。\n就我而言,一个 BannerGroup 可以有许多横幅,并且许多横幅属于同一个 BannerGroup。

\n\n

Mysql 表是...

\n\n
mysql> desc Banners;\n+------------------+--------------+------+-----+---------+-----------------------------+\n| Field            | Type         | Null | Key | Default | Extra                       |\n+------------------+--------------+------+-----+---------+-----------------------------+\n| banner_id        | int(11)      | NO   | PRI | NULL    | auto_increment              | \n| banner_name      | varchar(255) | YES  |     | NULL    |                             | \n| banner_group_id  | int(11)      | YES  | MUL | NULL    |                             | \n+------------------+--------------+------+-----+---------+-----------------------------+\n\nmysql> desc Banner_Group;\n+---------------------+--------------+------+-----+----------------+-----------------------------+\n| Field               | Type         | Null | Key | Default        | Extra                       |\n+---------------------+--------------+------+-----+----------------+-----------------------------+\n| group_id …
Run Code Online (Sandbox Code Playgroud)

mysql hibernate jpa

6
推荐指数
1
解决办法
6101
查看次数

为什么Hibernate有时会忽略FetchMode.JOIN?

我有一个@ManyToOne关系的实体,我想用一个查询检索,因此使用@Fetch(FetchMode.JOIN).有时Hibernate不尊重并发布N + 1 SELECT.随着有时我的意思是,因为我不知道是什么触发它,我有案件对不同的查询,这可能发生,或者不一样的类.

这是一个带有我使用的注释的简化实体:

@Entity
public class Employee {

    @ManyToOne
    @Fetch(FetchMode.JOIN)
    private Department department;

}
Run Code Online (Sandbox Code Playgroud)

CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class);

Root<Employee> root = criteriqQuery.from(Employee.class);

TypedQuery<Employee> typedQuery = entityManager.createQuery(criteriaQuery);

List<Employee> employees = typedQuery.getResultList();
Run Code Online (Sandbox Code Playgroud)

我希望一个查询来获取两个EmployeeDepartment,像

select ... from Employee join Department on ...
Run Code Online (Sandbox Code Playgroud)

相反,我得到所有N的Employee第一个选择,然后SELECT是所有Departments的N s(考虑没有缓存).

我发现了许多类似的问题,但他们的答案提出了解决方法,并没有解释为什么会发生这种情况.请避免建议使用延迟加载的答案:这不是我问的问题.

java optimization hibernate jpa

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

OneToMany(fetch=FetchType.EAGER) 是否执行 N+1 个查询

我正在使用 spring boot、spring data 和 Hibernate 开发一个应用程序。我有一个实体“Client”,它与另一个实体“Reservation”具有“onetomany”关系,如下所示:

@Entity
public class Client implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany( mappedBy = "client", fetch=FetchType.EAGER)
    @Fetch(value = FetchMode.JOIN)
    private Set<Reservation> reservations = new HashSet<>();
}
Run Code Online (Sandbox Code Playgroud)

我已经实现了 JpaRepository 接口,所以我可以操作客户端数据:

public interface ClientRepository extends JpaRepository<Client, Long> {}
Run Code Online (Sandbox Code Playgroud)

在服务类中,我实现了一种方法来查找数据库中的所有客户端:

@Service
public class ClientService {

@Autowired
private ClientRepository clientRepository;

@Transactional(readOnly = true)
public List<Client> findAll() {

    return clientRepository.findAll();
}}
Run Code Online (Sandbox Code Playgroud)

findAll() 的执行运行良好并返回所有客户端及其保留。但是,在我的 sql 日志中,我已经执行了 N+1 个查询(N 是客户端的计数),尽管我已经fetch=FetchType.EAGER在我的客户端实体中设置了这些查询。我认为 hibernate 将创建一个单一的查询,在其中加入所有必要的数据以检索客户及其预订。

因此,我被迫通过查询明确加入客户和预订:

    @Query("select client …
Run Code Online (Sandbox Code Playgroud)

database spring hibernate jpa

4
推荐指数
1
解决办法
2276
查看次数

ID为字符串时为N + 1(JpaRepository)

我有一个字符串ID为的实体:

@Table
@Entity
public class Stock {

    @Id
    @Column(nullable = false, length = 64)
    private String index;

    @Column(nullable = false)
    private Integer price;

}
Run Code Online (Sandbox Code Playgroud)

和JpaRepository:

public interface StockRepository extends JpaRepository<Stock, String> {
}
Run Code Online (Sandbox Code Playgroud)

当我打电话时stockRepository::findAll,我有N + 1问题:

日志简化了

选择s.index,s.price from stock s
select s.index,s.price from stock s where s.index =?

报价的最后一行调用约5K次(表的大小).另外,当我更新价格时,我会做下一步:

stockRepository.save(listOfStocksWithUpdatedPrices);
Run Code Online (Sandbox Code Playgroud)

在日志中我有N插入.
当id是数字时,我没有看到类似的行为.
在我的情况下,PS将id的类型设置为数字不是最佳解决方案.

更新1:
我忘了提到还有Trade与多对多关系的类Stock:

@Table
@Entity
public class Trade {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column …
Run Code Online (Sandbox Code Playgroud)

java hibernate jpa spring-data spring-data-jpa

3
推荐指数
1
解决办法
1474
查看次数

了解Hibernate Fetch

我知道hibernate是懒惰的默认提取策略,但有一些事情我不清楚,所以我希望你能解释一下.我想要做的是将标记为标记为起始图块的图块.

查询:

@NamedQuery(name = "Tile.findStartTileByGame", 
  query = "SELECT t FROM Tile t WHERE t.game = :game " +
    "and t.startTile = true and t.blockWalkable = false")
Run Code Online (Sandbox Code Playgroud)

瓦:

 public class Tile{ 

 @OneToOne(mappedBy="tile")
 private GameCharacter character;

 @OneToOne(mappedBy="tile")
 private GameObject gameObject;
Run Code Online (Sandbox Code Playgroud)

游戏:

 @OneToMany(mappedBy="game")
 private List<Tile> tiles;
Run Code Online (Sandbox Code Playgroud)

当我运行我的查询并且从不使用该对象时,hibernate仍然加入了我的角色和游戏对象.所以我有3个查询.我知道我可以通过fetch join来解决这个问题,但我的问题是为什么hibernate会同时获取两个引用?即使我使用fetch = FetchType.LAZY对它们进行注释,也会查询它.

我的DAO:

  public static Tile getFreeStartTile(EntityManager em, Game game) {
   TypedQuery<Tile> query = em.createNamedQuery("Tile.findStartTileByGame", Tile.class);
   query.setParameter("game", game);
  List<Tile> result = query.getResultList();
  ...
Run Code Online (Sandbox Code Playgroud)

在我解决这个问题之前,我想了解它为什么会发生.在此先感谢m

java hibernate jpa

0
推荐指数
1
解决办法
455
查看次数