【发布时间】:2018-12-06 08:52:14
【问题描述】:
我开始向你展示我的场景。
这是我的父对象:
@Entity
@Table(name="cart")
public class Cart implements Serializable{
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Id
@Column(name="id")
private Integer id;
@OneToMany(mappedBy="cart", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<CartItem> cartItems;
...
}
这是我的子对象:
@Entity
@Table(name="cart_item")
public class CartItem implements Serializable{
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Id
@Column(name="id")
private Integer id;
@ManyToOne
@JoinColumn(name="cart_id", nullable=false)
private Cart cart;
...
}
正如您在查看数据库时看到的那样,在表 cart_item(子对象)中,字段 cart_id 具有字段 id 的外键strong> 表 cart(父对象)。
这是我保存对象的方式:
1) 有一个读取 JSON 对象的 restController:
@RestController
@RequestMapping(value = "rest/cart")
public class CartRestController {
@Autowired
private CartService cartService;
@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.CREATED)
public void create(@RequestBody CartDto cartDto) {
cartService.create(cartDto);
}
}
2) 这是 CartService,它只是一个接口:
public interface CartService {
void create(CartDto cartDto);
}
这是 CartService 的实现:
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class CartServiceImpl implements CartService {
@Autowired
private CartDao cartDao;
@Override
public void create(CartDto cartDto) {
cartDao.create(cartDto);
}
}
CartDao 只是另一个接口,我只展示它的实现:
@Repository
public class CartDaoImpl implements CartDao {
@Autowired
private SessionFactory sessionFactory;
// in this method I save the parent and its children
@Override
public void create(CartDto cartDto) {
Cart cart = new Cart();
List<CartItem> cartItems = new ArrayList<>();
cartDto.getCartItems().stream().forEach(cartItemDto ->{
//here I fill the CartItem objects;
CartItem cartItem = new CartItem();
...
cartItem.setCart(cart);
cartItems.add(cartItem);
});
cart.setCartItems(cartItems);
sessionFactory.getCurrentSession().save(cart);
}
}
当我尝试保存新的 cart 及其 cart_item 时,我收到此错误:
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/webstore] threw
exception [Request processing failed; nested exception is
org.springframework.orm.hibernate5.HibernateOptimisticLockingFailureException: Object of
class
[com.depasmatte.webstore.domain.CartItem] with identifier [7]: optimistic locking failed;
nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by
another transaction (or unsaved-value mapping was incorrect) :
[com.depasmatte.webstore.domain.CartItem#7]] with root cause
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction
(or unsaved-value mapping was incorrect) : [com.depasmatte.webstore.domain.CartItem#7]
我想错误取决于当 Hibernate 尝试保存 cart_item 时,cart 的 id 还不存在!
在镜头中保存父对象及其子对象的正确方法是什么? 谢谢
【问题讨论】:
-
相关的代码可能就是你构建和保存数据的地方。
-
方法是事务性的吗?
-
嗨@AlanHay,我编辑了我的代码,现在应该更清楚了
-
嗨@Alien,我编辑了我的代码。如您所见,类 CartServiceImpl 是事务性的
-
如果我有 Set 而不是 List 怎么办?它的 Set,而不是 HashSet,所以我不能 dp mySet.add()
标签: java hibernate jpa one-to-many many-to-one