java.lang.IllegalStateException: org.hibernate.Tra

2019-08-09 06:58发布

My application has two entity Product and Category. When add product , user choose the category that product belong to. But when save the product to data base i meet the error

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation

the content of entity is 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
}

my jsp file

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

my Converter

public class CategoryConverter implements Converter<String, Category>{

    @Autowired
    private CategoryService categoryService;

    public Category convert(String id) {
        return categoryService.findById(Long.valueOf(id));
    }
}

thank for any help

2条回答
一夜七次
2楼-- · 2019-08-09 07:37

please add (cascade=CascadeType.ALL) into category field mapping of Product

@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "category_id", referencedColumnName = "id", nullable = false)
Category category;

and remove this line in ProductDAO:

entityManager.merge(product.getCategory());

NOTE: if your product's category is an existing one, you should load it first then set it to your product, this is normal flow. Do not new duplicated Category object.

查看更多
劫难
3楼-- · 2019-08-09 07:42

This my fixed code

@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);
}
查看更多
登录 后发表回答