這真讓我費解。無法在休眠中保存ManyToMany關係
我有以下類別:
Ingredient.java
@Entity
@Table(name = "INGREDIENTS", uniqueConstraints =
{@UniqueConstraint(columnNames = "NAME")})
public class Ingredient implements Serializable{
@Id
@GeneratedValue
@Column(name = "ingredient_id")
private Long id;
@Column(nullable = false, name = "name")
private String name;
@Column(nullable = false, name = "name")
private Long calories;
public Ingredient() {
}
public Ingredient(String name, Long calories) {
this.name = name;
this.calories = calories;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getCalories() {
return calories;
}
public void setCalories(Long calories) {
this.calories = calories;
}
public Long getId(){
return this.id;
}
public void setId(Long id) {
this.id = id;
}
}
Meal.java
@Entity
@Table(name = "MEALS")
public class Meal implements Serializable {
@ManyToOne
private User user;
@Id
@GeneratedValue
@Column(name = "meal_id")
private Long id;
@ElementCollection(targetClass = Ingredient.class)
private Set<Ingredient> ingredients = new HashSet<>(0);
//More fields and constructors
@ManyToMany(targetEntity = Ingredient.class, cascade = CascadeType.ALL)
@JoinTable(name = "ingredient_meal", joinColumns = {@JoinColumn(name = "meal_id")}, inverseJoinColumns = {@JoinColumn(name = "ingredient_id")})
public List<Ingredient> getIngredients() {
return ingredients;
}
public void setIngredients(List<Ingredient> ingredients) {
this.ingredients = ingredients;
}
public Long getId(){
return this.id;
}
public void setId(Long id) {
this.id = id;
}
這是我堅持的實體代碼:
SessionFactory sessionFactory =
entityManagerFactory.unwrap(SessionFactory.class);
Session session = sessionFactory.openSession();
session.beginTransaction();
/***/
Meal coolMeal = new Meal(user, new Date(115, 0, 8), new Time(19, 0, 0), "8 -
Moules Frites", 1000L);
coolMeal.getIngredients().add(new Ingredient("Fish2", 100L));
session.persist(coolMeal);
try{
session.getTransaction().commit();
}catch(Throwable e){
e.printStackTrace();
throw e;
}
session.close();
但我不斷收到此異常:
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: calories.tracker.app.model.Ingredient
at org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:294)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:537)
at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:165)
at org.hibernate.persister.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:899)
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1308)
at org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:67)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:349)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
at
但是如果我堅持的對象以這種方式:
Ingredient i1 = new Ingredient("Potatoes2", 100L);
session.persist(i1);
Meal coolMeal = new Meal(user, new Date(115, 0, 8), new Time(19, 0, 0),
"8 - Moules Frites", 1000L);
coolMeal.getIngredients().add(i1);
它工作正常,爲什麼?一切都與here完全一樣。
首先,要保證訪問類型的一致性,即將所有註釋放置在任何字段或屬性中,而不是混合。那我們再來看看。 – ram
宣稱'成份'屬於'Set'類型,但getter返回'List'? –
對不起,嘗試使用列表而不是Set如示例 – Santi