简体   繁体   English

当实体中存在关系时,我可以只使用实体的 id 而不是从数据库中获取实体吗?

[英]Can I use only Entity's id instead of fetching an entity from DB when there is a relationship in an Entity?

I am using Spring Data JPA with Hibernate.我正在使用 Spring 数据 JPA 和 Hibernate。

Lets say I have the following entity defined:假设我定义了以下实体:

@Entity
@Table(name = "foods")
public class Food {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "food_id")
    private Long foodId;


    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "food_type_id")
    @NotNull
    private FoodType foodType;
    
    ...
}


@Entity
@Table(name = "food_types")
public class FoodType {
    
    public static final Integer PERISHABLE;
    public static final Integer NON_PERISHABLE;

    @Id
    @Column(name = "food_type")
    private Integer foodTypeId;

    private String name;
    
    ...
}

Every time when I want to create a Food entity and save it to the database, currently code looks like this:每次我想创建一个Food实体并将其保存到数据库时,当前代码如下所示:

Food food = new Food();
FoodType foodType = foodTypeRepository.findById(FoodType.PERISHABLE); // Call to DB to get Entity
food.setFoodType(foodType);
....

foodRepository.save(food);

If we consider FoodType to be constant in the DB.如果我们认为 FoodType 在数据库中是常量。 Can I use it like this:我可以这样使用它:

Food food = new Food();
FoodType foodType = new FoodType();
foodType.setFoodTypeId(FoodType.PERISHABLE); // No Call to DB
food.setFoodType(foodType);
....

foodRepository.save(food);

I have tested it and yes I can use it that way, hibernate will save the Food entity, but are there any downsides, pitfalls, etc... I am not seeing.我已经对其进行了测试,是的,我可以这样使用它,hibernate 将保存Food实体,但是否有任何缺点、陷阱等……我没有看到。

PS. PS。 This is just a simple example illustrating the idea, it is part of old legacy project which I cannot modify to remove constant from DB, and use an enum instead.这只是一个说明这个想法的简单示例,它是旧遗留项目的一部分,我无法修改它以从数据库中删除常量,而是使用枚举。

To avoid extra call to DB you should use:为避免额外调用 DB,您应该使用:

FoodType foodType = foodTypeRepository.getOne(FoodType.PERISHABLE); 

under the hood it calls EntityManager.getReference that obtain a reference to an entity without having to load its data as opposed to the foodTypeRepository.findById that lead to call EntityManager.find that obtain an entity along with its data .在引擎盖下,它调用EntityManager.getReference获得对实体的引用,而无需加载其数据,而不是导致调用EntityManager.findfoodTypeRepository.findById获得实体及其数据

See also this section of the hibernate documentation.另请参阅 hibernate 文档的此部分

PS You can not use: PS你不能使用:

Food food = new Food();
FoodType foodType = new FoodType();
foodType.setFoodTypeId(FoodType.PERISHABLE);

as in this case hibernate consider foodType as a transient entity (not associated with a persistence context ) and will try to save it as a new record if you have a proper cascading on your @ManyToOne association.在这种情况下 hibernate 将foodType视为一个临时实体(与持久性上下文无关),如果您在@ManyToOne关联上有适当的级联,将尝试将其保存为新记录。

PSS As it's mentioned in the documentation the method JpaRepository#getOne(ID) is deprecated and you should use JpaRepository#getById(ID) instead. PSS 正如文档中提到的那样,方法JpaRepository#getOne(ID)已被弃用,您应该改用JpaRepository#getById(ID)

You do not need to fetch the entity associated with FoodType.PERISHABLE in order to set the relation on a Food entity to it and I'm not aware of any side effects or pitfalls of using FoodType.PERISHABLE directly as long it is a valid FoodType id.您无需获取与FoodType.PERISHABLE关联的实体即可将Food实体上的关系设置为它,而且我不知道直接使用FoodType.PERISHABLE的任何副作用或陷阱,只要它是有效的FoodType ID。

As others mentioned, you could also use JpaRepository#getById(ID id) and that's probably the more canonical way of addressing this problem:正如其他人提到的,您也可以使用JpaRepository#getById(ID id)这可能是解决此问题的更规范的方法:

T getById(ID id) Returns a reference to the entity with the given identifier. T getById(ID id) 返回对具有给定标识符的实体的引用。 Depending on how the JPA persistence provider is implemented this is very likely to always return an instance and throw an EntityNotFoundException on first access.根据 JPA 持久性提供程序的实现方式,这很可能总是返回一个实例并在首次访问时抛出 EntityNotFoundException。 Some of them will reject invalid identifiers immediately.他们中的一些人会立即拒绝无效的标识符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何仅从关系中检索属性而不是实体? - How can I retrieve only an attribute instead of the Entity from a relationship? 我可以使用什么代替实体bean? - What can I use instead of an entity bean? 澄清术语——“水化”JPA 或 Hibernate 实体在从数据库中获取实体时意味着什么 - Clarifying terminology - What does "hydrating" a JPA or Hibernate entity mean when fetching the entity from the DB 如何仅检索ID而不是关联的实体? - How do I retrieve only the ID instead of the Entity of an association? 持久化实体时设置 OneToMany 关系的 id - Setting id of OneToMany relationship when persisting entity JPA 使用 Map<ID, Entity> 而不是列表<Entity> - JPA use Map<ID, Entity> instead of List<Entity> 当我只知道实体的ID时,如何获得它的父密钥? - How can I get the parent key of an entity when I only know its id? 仅当 JpaRepository 为 null 时,我如何才能生成实体 ID? - How can i generate an entity id only if it is null with JpaRepository? 我可以在 equals/hashCode 中使用实体的 ID 并回退到实例相等吗? - Can I use an Entity's ID in equals/hashCode with fallback to instance equality? 如何正确使用 UUID 作为 @Entity 的 @Id? - How can I use an UUID as an @Id for my @Entity properly?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM