2014-12-07 25 views
1

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

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 

回答

0

你有没有实现的equals()和hashCode()方法正确在Receipe和Indgredient类?如果不是,那么这可能是indgredient表中的行未被删除的原因。阅读this文章了解更多详情。

+0

我已经在这两个类中实现了'equal()'和'hashcode()'方法。我已经使用Eclipse内置功能(Source> Generate equal()和hascode())来生成这些功能。但问题依然存在,数据也没有从INGREDENT表中删除。 – user92161 2014-12-07 07:32:40

+0

我使用'getSession()。merge(recipe)'而不是'getSession()。saveOrUpdate(recipe)'并且它工作。我正在阅读其他论坛/文章,并从那里获得了这个想法。我不确定是什么改变了,但代码现在可以完美运行。你对此有何看法? – user92161 2014-12-07 08:00:19

+0

不确定这是否适用于您的用例 - http://www.stevideter.com/2008/12/07/saveorupdate-versus-merge-in-hibernate/ – 2014-12-07 11:10:16