Java 无法在Hibernate中保存多个关系

Java 无法在Hibernate中保存多个关系,java,hibernate,jpa,many-to-many,Java,Hibernate,Jpa,Many To Many,这真让我困惑 我有以下课程: component.java @Entity @Table(name = "INGREDIENTS", uniqueConstraints = {@UniqueConstraint(columnNames = "NAME")}) public class Ingredient implements Serializable{ @Id @GeneratedValue @Column(name = "ingredient_id") private Long id;

这真让我困惑

我有以下课程:

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

fine.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;
}
@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;
}
但我一直得到这样一个例外:

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);

它很好用,为什么?所有内容都完全相同。

您为
成分
字段声明了两个映射。
一个在字段中,另一个在getter中:

@ElementCollection(targetClass = Ingredient.class)
private Set<Ingredient> ingredients = new HashSet<>(0);    
 ....        
@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;
}
@ElementCollection
设计用于映射非实体类,而
component
是一个实体:

根据Javadoc:

元素集合

定义基本类型或可嵌入类的实例集合


您必须使用
@OneToMany(mappedBy=“Ord”,cascade=CascadeType.ALL,fetch=FetchType.LAZY)
,用您的实体名称替换
Ord

首先,访问类型要一致,即将所有注释放在字段或属性中,不要混合。然后让我们再看一看。声明的
成分
属于
集合
类型,但getter返回
列表
?抱歉,在尝试使用列表而不是集合时,复制/粘贴会出错,如示例中所示。这不是一个单一的,而是多个单向的