有 Java 编程相关的问题?

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

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

我在Hibernate中使用Spring数据JPA

假设我定义了以下实体:

@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;
    
    ...
}

每次我想要创建Food实体并将其保存到数据库时,当前代码如下所示:

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

foodRepository.save(food);
<如果我们考虑食物类型在dB中是恒定的。我可以这样使用它吗:

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

foodRepository.save(food);

我已经对它进行了测试,是的,我可以这样使用它,hibernate将保存Food实体,但是是否有任何缺点、陷阱等。。。我没有看见

这只是一个简单的例子来说明这个想法,它是旧遗留项目的一部分,我不能修改它来从数据库中删除常量,而是使用枚举


共 (2) 个答案

  1. # 1 楼答案

    您不需要获取与FoodType.PERISHABLE关联的实体来设置Food实体与它的关系,我不知道直接使用FoodType.PERISHABLE的任何副作用或陷阱,只要它是有效的FoodTypeid

    正如其他人提到的,你也可以使用JpaRepository#getById(ID id),这可能是解决这个问题的更规范的方法:

    T getById(ID id) Returns a reference to the entity with the given identifier. 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. Some of them will reject invalid identifiers immediately.

  2. # 2 楼答案

    为了避免额外呼叫DB,您应该使用:

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

    在引擎盖下,它调用EntityManager.getReference来获取对实体的引用,而不必加载其数据,而foodTypeRepository.findById则导致调用EntityManager.find来获取实体及其数据

    另请参见hibernate文档的this section

    请注意,您不能使用:

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

    如在本例中,Hibernate考虑^ {< CD4>}作为Time实体(不与A^ {A2}关联),并且如果在{{{CD5}}关联上有正确的cascading,则尝试将其保存为新记录。

    另外,正如documentation中提到的,方法JpaRepository#getOne(ID)已被弃用,您应该使用JpaRepository#getById(ID)