我的数据库类别和项目中有很多与很多相关。 我的目标是当我将项目添加到类别中的项目列表时,这些项目将自动添加到数据库中。 我认为通过CascadeType.PERSIST对类别中的项目列表进行注释将完成工作,但事实并非如此。放入所有CascaseTypes枚举值也不起作用。 每次提交事务时我都会收到以下异常:
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: il.co.site_building.webutils.shop.Item
只有当我使用CascadeType.ALL对其进行注释时,才能正确保存这些项目。
类别的代码:
public Category(Integer uid,
String name,
String displayName,
Category parent,
List<Category> subCategories,
List<Item> items){
m_uid = uid;
m_name = name;
m_displayName = displayName;
m_parent = parent;
m_subCategories = subCategories;
m_itemsInCategory = items != null ? items : new LinkedList<>();
}
@ManyToMany(cascade = CascadeType.PERSIST) //Doesn't work. Only CascadeType.ALL will work.
@JoinTable(name = "items_categories",
joinColumns = {@JoinColumn(name="category") },
inverseJoinColumns = {@JoinColumn(name = "item")})
public List<Item> getItemsInCategory(){return m_itemsInCategory;}
项目的代码:
public Item(Integer uid,
String name,
String displayName,
String description,
BigDecimal price,
Integer orderIndex,
String serialNo,
AttributeType attributeType,
List<ItemAttribute> itemAttributes,
List<Category> categories){
m_uid = uid;
m_name = name;
m_displayName = displayName;
m_description = description;
m_price = price.setScale(PRICE_SCALE);
m_orderIndex = orderIndex;
m_serialNo = serialNo;
m_attributeType = attributeType;
m_itemAttributes = itemAttributes != null ? itemAttributes : new LinkedList<>();
m_categories = categories != null? categories : new LinkedList<>();
}
@ManyToMany(mappedBy = "itemsInCategory")
public List<Category> getCategories(){return m_categories;}
插入项目的代码(假设类别已存在):
public static final String SHIRT_NAME = "shirt";
public static final String SHIRT_DISPLAY_NAME = "shirt display";
public static final String SHIRT_DESCRIPTION = "shirt description";
public static final BigDecimal SHIRT_PRICE = new BigDecimal("2.01");
public static final Integer SHIRT_ORDER_INDEX = 1;
public static final String SHIRT_SERIAL_NUMBER = "shirt_sn";
public static final Item SHIRT = new Item(null,
SHIRT_NAME,
SHIRT_DISPLAY_NAME,
SHIRT_DESCRIPTION,
SHIRT_PRICE,
SHIRT_ORDER_INDEX,
SHIRT_SERIAL_NUMBER,
AttributeTypeTest.ATTRIBUTE_TYPE_SIZE,
null, null);
session.beginTransaction();
Query query.setParameter("uid", CategoryTest.CATEGORY_SHIRTS.getUid()); //This category was persisted properly somewhere else
Category category = (Category)query.uniqueResult();
List<Item> itemsInCategory = category.getItemsInCategory();
SHIRT.getCategories().add(category); itemsInCategory.add(SHIRT);
session.getTransaction().commit();
答案 0 :(得分:1)
因此在使用带有JPA注释类的本机API时会出现Hibernate问题。
当使用CascadeType.PERSIST
注释关系时,Hibernate不会持久保存子对象,但仅适用于CascadeType.ALL
注释关系。
但是,如果您通过JPA API使用Hibernate(因此EntityManger而不是Session,其余代码几乎完全相同),
然后,CascadeType.PERSIST
和CascadeType.ALL
都会触发子元素的持久性。这显然是JPA规范的一部分(感谢Chris指出它),即使它在javadocs中被省略了。
我总是错误地认为只有明确的persist()请求是级联的。
如果您的项目还不晚,您可以考虑使用JPA标准而不是hibernate API。对于新代码,转换几乎是无缝的(持久而不是保存,删除而不是删除....)