2017-01-20 3 views
1

Я создаю приложение, и у меня есть ManyToMany соотношение между Recipe и Ingredients, , но когда я пытаюсь вставить новую строку в RecipeIngredient с помощью JPA 2.1 я получил:отдельностоящий объект при использовании ManyToMany в JPA 2.1

Вызвано: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: удаленный объект, прошедший до persist.

Это мои объекты: `

@Entity 
@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
@CrossCheck 
public class Ingredient implements ValidEntity { 

static final String PREFIX = "com.architech.sales.ingredient.entity."; 
public static final String FIND_ALL = PREFIX + "FIND_ALL"; 
public static final String FIND_BY_ID = PREFIX + "FIND_BY_ID"; 

@Id 
@GeneratedValue 
private long id; 

@NotNull 
private String label; 
private String description; 

// added just to reply to @Maciej-Kowalski 
@OneToMany(targetEntity = RecetteIngredient.class, mappedBy = "ingredient") 
private List<RecetteIngredient> recetteIngredients; 

@Version 
private long version; 
// Getter/Setter 

} 

@Entity 
@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
@CrossCheck 
public class Recette implements ValidEntity{ 

static final String PREFIX = "sales.recette.entity.Recette."; 
public static final String FIND_ALL = PREFIX + "FIND_ALL"; 
public static final String FIND_BY_ID = PREFIX + "FIND_BY_ID"; 

@Id 
@GeneratedValue 
private long id; 

@Size(min = 1, max = 256) 
private String label; 
private String description; 

@OneToMany(targetEntity = RecetteIngredient.class, mappedBy = "recette") 
private List<RecetteIngredient> recetteIngredients; 

@Version 
private long version; 

// Getter/Setter 
} 
` 

`

@Entity 
@IdClass(RecetteIngredientPK.class) 
public class RecetteIngredient implements Serializable{ 

@Id 
private long id; 
private double qte; 

@Id 
@ManyToOne(targetEntity = Ingredient.class) 
private Ingredient ingredient; 

@Id 
@ManyToOne(targetEntity = Recette.class) 
private Recette recette; 

// Getter/Setter 
} 
` 

и моя настойчивость блок

<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> <persistence-unit name="prod" transaction-type="JTA"> <properties> <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/> <!--<property name="hibernate.enable_lazy_load_no_trans" value="true" />--> </properties> </persistence-unit> </persistence>

Это StackTrace:

`

Caused by: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.architech.sales.ingredient.entity.Ingredient 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692) 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602) 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608) 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1171) 
    at org.jboss.as.jpa.container.AbstractEntityManager.merge(AbstractEntityManager.java:565) 
    at com.architech.sales.recette_ingredient.boundary.RecetteIngredientManager.save(RecetteIngredientManager.java:47) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
` 

и это, как я пытаюсь persiste RecetteIngredient:

` 
@Stateless 
@Interceptors(BoundaryLogger.class) 
public class RecetteIngredientManager { 

@PersistenceContext 
EntityManager em; 

public RecetteIngredient findById(long id) { 
    return this.em.find(RecetteIngredient.class, id); 
} 

public void delete(long id) { 
    try { 
     RecetteIngredient reference = this.em.getReference(RecetteIngredient.class, id); 
     this.em.remove(reference); 
    } catch (EntityNotFoundException e) { 
     //we want to remove it... 
    } 
} 

public RecetteIngredient save(RecetteIngredient recetteIngredient) { 
    return this.em.merge(recetteIngredient); 
} 

} 

`

ответ

1

В вашей linking add add merge Дополнительный каскад на @ManyToOne отображений:

@Entity 
@IdClass(RecetteIngredientPK.class) 
public class RecetteIngredient implements Serializable{ 

@Id 
private long id; 
private double qte; 

@Id 
@ManyToOne(targetEntity = Ingredient.class, cascade = CascadeType.MERGE) 
private Ingredient ingredient; 

@Id 
@ManyToOne(targetEntity = Recette.class, cascade = CascadeType.MERGE) 
private Recette recette; 

Это будет консультировать PersistenceContext слить также сущность Ингредиента и Recette, если они происходят, чтобы быть отсоединены в то время.

Если вы не можете изменить аннотации, то вы должны сохраняться/слияния Ингредиент и Recette объекты вручную перед persising в связующую таблицу:

public RecetteIngredient save(RecetteIngredient recette) { 
    this.em.merge(recette.getIngredient()); 
    this.em.merge(recette.getRecette()); 

    return this.em.merge(recette); 
} 

Конечно, это обходной путь, и первый подход является определенно более элегантным и целесообразным.

+0

Благодарим вас за ответ, Я протестировал оба решения, но все равно получаю ту же ошибку. –

+0

попробуйте добавить persist cascade - cascade = {CascadeType.MERGE, CascadeType.PERSIST} –

+0

Я даже попробовал 'cascade = CascadeType.ALL' и все еще получал ту же ошибку, –

Смежные вопросы