MDP*_*MDP 5 java hibernate jpa one-to-many many-to-one
我开始向您展示我的情况。
这是我的父对象:
@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;
...
}
Run Code Online (Sandbox Code Playgroud)
这是我的孩子对象:
@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;
...
}
Run Code Online (Sandbox Code Playgroud)
正如您看到数据库一样,在表cart_item(子对象)中,字段cart_id具有指向表cart(父对象)的字段ID的外键。
这是我保存对象的方式:
1)有一个restController,它读取一个JSON对象:
@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);
}
}
Run Code Online (Sandbox Code Playgroud)
2)这是CartService,仅是一个接口:
public interface CartService {
void create(CartDto cartDto);
}
Run Code Online (Sandbox Code Playgroud)
这是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);
}
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试保存新购物车及其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]
Run Code Online (Sandbox Code Playgroud)
我猜想误差取决于事实,当Hibernate的尝试保存一个cart_item,该ID的的车还不存在!
在镜头中保存父对象及其子对象的正确方法是什么?谢谢
Ali*_*ghi 12
对于双向关系,如下所示:
这是示例代码:
public class Parent {
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "fk_parent")
private List<Child> children;
}
public class Child {
@ManyToOne
@JoinColumn(name = "fk_parent")
private Parent parent;
}
Run Code Online (Sandbox Code Playgroud)
Tar*_*ras 11
这是您应该遵循的规则列表,以便能够一次性存储父实体及其子实体:
PERSIST应该启用级联类型(CascadeType.ALL也可以)映射问题:
@Column(name="id")从两个实体中删除cartItems 私人。由于Hibernate使用的是自己的实现,因此List您永远不要直接通过setter更改它。private List<CartItem> cartItems = new ArrayList<>();@ManyToOne(optional = false)而不是nullable = false内部@JoinColumnfetch = FetchType.LAZY收藏最好使用辅助方法来设置关系。例如,类Cart应具有以下方法:
public void addCartItem(CartItem item){
cartItems.add(item);
item.setCart(this);
}
Run Code Online (Sandbox Code Playgroud)设计问题:
save使用Spring Data JPA存储库的类似样板的方法| 归档时间: |
|
| 查看次数: |
5203 次 |
| 最近记录: |