如何使用Spring-JPA和Hibernate使用@OneToMany和@ManyToOne注释声明数据库映射

时间:2013-02-24 21:46:46

标签: java spring hibernate jpa

假设我有以下商业模式:

用户最多可拥有n辆

这是我的 DAO / 类用户:

@Entity
@Table(name="USER")
public @Data class User extends AbstractPersistable<Long> {
    @OneToMany(cascade=CascadeType.PERSIST, mappedBy="owner")
    private Set<Vehicle> vehicles = new HashSet<Vehicle>();
}

这是车辆类:

@Entity
@Table(name="VEHICLE")
public @Data class Vehicle extends AbstractPersistable<Long> {
    @ManyToOne(optional = false)
    @JoinColumn(name = "user_id")
    User owner;
}

我希望能够像这样为新用户保存新的车辆:

User user = new User();
user.setName("Fred"); // other setters omitted

Vehicle vehicle = new Vehicle();
vehicle.setEngine("..."); // other setters omitted 

user.getVehicles().add(vehicle);
userService.saveUser(user);

userService.saveUser()是一个服务层方法,注释为 @Transactional 并调用userRepository.save(user); (请参阅底部以获取Repository类的摘录)


现在有几个问题,因为我的解决方案没有按预期运行:

1。甚至可以保存用户对象并自动保留用户对象中的Vehicle-Set吗?
2. 这是最佳做法吗?我知道用户是拥有实体。我想要在移除用户时移除用户的所有车辆 3。或者我是否总是要做 vehicle.setOwner(user); 这样的事情? 4. 从您的角度来看,最佳解决方案是什么?

我读了很多关于拥有实体和JoinColumn / mappedBy的内容。但现在我比以前更困惑了。


此外,这是我的UserRepository的摘录:

import org.springframework.data.jpa.repository.JpaRepository;
import org.myproject.domains.User;

public interface UserRepository extends JpaRepository<User, Long> { 
User findByLoginName(String loginName); 
}

2 个答案:

答案 0 :(得分:0)

如果只有持续存在的情况,

CascadeType.PERSIST会一直存在vehicles

我建议您使用CascadeType.ALL。因此,当您删除用户时,vehicles将被删除,并且如果您更新/保留用户,则会更新/保留车辆。

如果您想从车辆访问用户

vehicle.setOwner(用户)是必要的。

答案 1 :(得分:0)

您当然需要在User实体的对象中设置Vehicle的引用,否则Hibernate将无法识别该关系。

我还建议将@OneToMany

一起使用
  • cascade=CascadeType.ALL进行正确的级联操作(请注意,通常情况下,您根本不会Vehicle单独触摸User
  • fetch = FetchType.EAGER以避免LazyInitializationException(请注意,您的JPA配置中不能有超过1个EAGER关系)
  • orphanRemoval = true用于在用户更新后清理“不必要的”车辆