java - Hibernate 不删除外键行(而是将其设置为 NULL)

标签 java spring hibernate

我有一个 RECIPE 表,它与 INGREDIENT 表具有 OneToMany 关系,因为一个食谱可以有很多成分。问题是,如果用户删除了一个成分(它通过前端将所有字段(ingredient_idingredient)设置为 NULL),那么包含两个表关系的行 RECIPE_INGREDIENT 已删除,但 Ingredient 表中的行仍然存在。我们不能告诉 Hibernate 也删除那些行吗?

Oracle 表

create table recipe(id number primary key,
                    name varchar2(25) unique);

create table ingredient(ingredient_id number(4) primary key,
                    ingredient varchar2(40));

create table recipe_ingredient(recipe_id number(4),
                           ingredient_id number(4),
                           constraint recipe_fk foreign key(recipe_id)
                           references recipe(recipe_id),
                           constraint ingredient_fk foreign
                           key(ingredient_id) references
                           ingredient(ingredient_id));

成分和配方 POJO

@Entity
@Table(name = "ingredient", uniqueConstraints={
        @UniqueConstraint(columnNames="INGREDIENT_ID")
})
public class Ingredient implements Serializable {   
    @Id
    @Column(name = "INGREDIENT_ID", unique=true, nullable=false)
    @SequenceGenerator(name="seq_ingredient", sequenceName="seq_ingredient")
    @GeneratedValue(strategy=GenerationType.AUTO, generator="seq_ingredient")
    private Integer ingredientId;

    @Column(name = "INGREDIENT")
    private String ingredient;

    /*@ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="RECIPE_ID")
    private Recipe recipe;*/

    //getter and setters



@Entity
@Table(name = "recipe")
public class Recipe implements Serializable {    
    @Id
    @Column(name = "id")
    private Integer id;

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

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @JoinTable(name = "recipe_ingredient", joinColumns = { @JoinColumn(name = "recipe_id") }, inverseJoinColumns = { @JoinColumn(name = "ingredient_id") })
    private List<Ingredient> ingredients;

//getters and setter
}

DAO 代码

public class RecipeDaoImpl implements RecipeDao {
    public void addRecipe(Recipe recipe) {
        getSession().saveOrUpdate(recipe);
    }
}

日志显示 INGREDIENT 表中的行仍然存在,而 Hibernate 只是从“RECIPE_INGREDIENT”表中删除行。

请看下面删除ingredient_idnull。在这两种情况下,它都将 ingredient.recipe_id 更新为 NULL。

Received following from frontend:
RecipeController - Recipe[recipeId=126,name=Sandwich,ingredients=[Ingredient[ingredientId=270,ingredient=Salt],[ingredientId=<null>,quantity=<null>]]]

Hibernate: update RECIPE set NAME=? where RECIPE_ID=?
Hibernate: update ingredient set INGREDIENT=? where INGREDIENT_ID=?
Hibernate: delete from recipe_ingredient where recipe_id=?
Hibernate: insert into recipe_ingredient (recipe_id, ingredient_id) values (?, ?)

所以数据库表有,

INDREDIENT
INGREDIENT_ID   INGREDIENT
271             Salt    
272             Sugar

RECIPE_INDGREDIENT
RECIPE_ID   INDREDIENT_ID
126         271

最佳答案

我通过将 insertable = false, updatable = false 作为属性添加到 @JoinColumn

解决了这个问题

像这样:

@JoinColumn(name="RECIPE_ID", insertable = false, updatable = false)

关于java - Hibernate 不删除外键行(而是将其设置为 NULL),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27309075/

相关文章:

java - 将微秒时间转换为毫秒时间

java - @Resource 与 @Autowired

java - 在 Hibernate Criteria 中将日期转换为字符串

java - 使用 Hibernate 保存对象时获取 DataViolationIntegrityException

java - JDOFatalUserException : Persistence Manager has been closed

Java 正则表达式组替换

java - 单击按钮打开拨号盘,该字符串例如 String str = "*#06#"应该在拨号盘中打开。

java - 模式观察者和Spring

java - 在 bootstrap.properties 文件中配置 Spring Cloud Config 的机制是什么?

java - 有没有一种方法可以在 Hibernate 中加载对象而无需编写查询或具有 ID?