gpt4 book ai didi

java - hibernate :无法使用 CascadeType.PERSIST

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:00:53 26 4
gpt4 key购买 nike

我的数据库类别和项目在多对多相关。我的目标是,当我将项目添加到类别中的项目列表时,这些项目将自动添加到数据库中。我认为通过 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();

最佳答案

因此,当使用带有 JPA 注释类的 native API 时,这是 Hibernate 的问题。

当使用 CascadeType.PERSIST 注释关系时,Hibernate 不会保留子对象,但仅适用于 CascadeType.ALL 注释关系。

但是,如果您通过 JPA API 使用 Hibernate(因此 EntityManger 而不是 Session,其余代码几乎相同),然后 CascadeType.PERSISTCascadeType.ALL 都会触发子元素的持久化。这显然是 JPA 规范的一部分(感谢 Chris 指出),即使它在 javadoc 中被省略了。我一直错误地认为只有显式的 persist() 请求才会被级联。

如果对你的项目来说还不算太晚,你可以考虑使用 JPA 标准而不是 hibernate API。新代码的转换几乎是无缝的(坚持而不是保存,删除而不是删除......)

关于java - hibernate :无法使用 CascadeType.PERSIST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29376205/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com