我的应用程序有两个实体产品和类别。添加产品时,用户选择产品所属的类别。但是当我将产品保存到数据库时,我遇到了错误
org.springframework.web.util.NestedServletException:请求处理失败;嵌套异常是java.lang.IllegalStateException:org.hibernate.TransientPropertyValueException:非null属性引用瞬态值 - 必须在当前操作之前保存瞬态实例
实体的内容是 Category.java
@Entity
@Table(name="category")
public class Category {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
@Column(name="category_name")
private String categoryName;
@Column(name="description")
private String description;
@OneToMany(mappedBy = "category", fetch=FetchType.LAZY)
private Set<Product> products;
//getter and setter method
}
Product.java
@Entity
@Table(name="product")
public class Product {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
@Column(name="name")
@NotNull
@NotEmpty
private String name;
@Column(name="description")
private String description;
@Column(name="manufacture")
private String manufacture;
@Column(name="price")
private long price;
@Column(name="image_name")
private String imageName;
@ManyToOne
@JoinColumn(name = "category_id", referencedColumnName = "id", nullable = false)
Category category;
//getter and setter method
}
ProductDAO.java
@Repository("ProductDAO")
@Transactional
public class ProductDAO {
@PersistenceContext
private EntityManager entityManager;
public EntityManager getEntityManager() {
return entityManager;
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
public void create(Product product) {
entityManager.merge(product.getCategory());
entityManager.persist(product);
}
//other method
}
我的jsp文件
<form:form method="post" commandName="product" action="add.html" enctype="multipart/form-data">
Productname <form:input path="name"/>
<form:errors path="name" class ="error"/><br>
description <form:input path="description"/><br>
price <form:input path="price"/><br>
manufacture <form:input path="manufacture"/><br>
Category
<form:select path="category">
<form:options items="${categories}" itemValue="id" itemLabel="categoryName" />
</form:select>
<form:errors path="category" class ="error"/><br>
<br/>
Product image<input type="file" name="file" />
<form:errors path="imageName" class ="error"/><br>
<input type="submit" class="register" value="Save">
</form:form>
我的转换器
public class CategoryConverter implements Converter<String, Category>{
@Autowired
private CategoryService categoryService;
public Category convert(String id) {
return categoryService.findById(Long.valueOf(id));
}
}
感谢您的帮助
答案 0 :(得分:3)
请将(cascade = CascadeType.ALL)添加到Product
的类别字段映射中@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "category_id", referencedColumnName = "id", nullable = false)
Category category;
并在ProductDAO中删除此行:
entityManager.merge(product.getCategory());
注意:如果您的产品类别是现有产品,则应首先加载它,然后将其设置为您的产品,这是正常流程。不要重复新的Category对象。
答案 1 :(得分:2)
这是我的固定代码
@Transactional
public void create(Product product) {
Category category=categoryDAO.findById(product.getCategory().getId());
category.getProducts().add(product);
categoryDAO.edit(category);
product.setCategory(category);
this.productDAO.create(product);
}