spring 数据 jpa 中的 OneToOne CascadeType
OneToOne CascadeType in spring data jpa
我在 spring data JPA
中使用 OneToOne
并且我想从 Address
table 不接触用户。但是我不能。
如果我去掉User
,在这种情况下Address
就去掉了,这样就好了。
但是如何在不触及 User
的情况下删除 Address
?
https://github.com/myTestPercon/TestCascade
User.Java
@Entity
@Table(name = "user", schema = "testCascade")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
private Address address;
// Getter and Setter ...
}
Address.java
@Entity
@Table(name = "address", schema = "testCascade")
public class Address implements Serializable {
@Id
private Long id;
@Column(name = "city")
private String city;
@OneToOne
@MapsId
@JoinColumn(name = "id")
private User user;
// Getter and Setter ...
}
DeleteController.java
@Controller
public class DeleteController {
@Autowired
ServiceJpa serviceJpa;
@GetMapping(value = "/deleteAddressById")
public String deleteAddressById () {
serviceJpa.deleteAddressById(4L);
return "redirect:/home";
}
}
public class Address {
@Id
private Long id;
@MapsId
@JoinColumn(name = "id")
private User user;
}
将 @JoinColumn(name = "id")
重命名为 @JoinColumn(name = "user_id")
你不能说指向用户的列就是地址的 ID
你的映射有误,这就是问题所在。
试试下面的方法看看
User.java
@Entity
@Table(name = "user", schema = "testCascade")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name="foriegn key column in user table for address example.. address_id")
private Address address;
// Getter and Setter ...
}
Address.java
@Entity
@Table(name = "address", schema = "testCascade")
public class Address implements Serializable {
@Id
private Long id;
@Column(name = "city")
private String city;
//name of the address variable in your user class
@OneToOne(mappedBy="address",
cascade={CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH})
private User user;
// Getter and Setter ...
}
为了解决这个问题,需要阅读hibernate Documentation Hibernate Example 162
, Example 163
, Example 164
.
我还建议看看这个
这帮助我解决了这个问题。
而且你还需要指定参数orphanRemoval = true
User.java
@Entity(name = "User")
@Table(name = "user", schema = "testother")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private Address address;
public void addAddress(Address address) {
address.setUser( this );
this.address = address;
}
public void removeAddress() {
if ( address != null ) {
address.setUser( null );
this.address = null;
}
}
// Getter and Setter
}
Address.java
@Entity(name = "Address")
@Table(name = "address", schema = "testother")
public class Address implements Serializable {
@Id
private Long id;
@Column(name = "city")
private String city;
@OneToOne
@MapsId
@JoinColumn(name = "id")
private User user;
// Getter and Setter
}
删除控制器。java
@Controller
public class DeleteController {
@Autowired
ServiceJpa serviceJpa;
@GetMapping(value = "/deleteUser")
public String deleteUser () {
User user = serviceJpa.findUserById(2L).get();
user.removeAddress();
serviceJpa.saveUser(user);
return "/deleteUser";
}
}
或自定义 SQL 查询。
@Repository
public interface DeleteAddress extends JpaRepository<Address, Long> {
@Modifying
@Query("delete from Address b where b.id=:id")
void deleteBooks(@Param("id") Long id);
}
我在 spring data JPA
中使用 OneToOne
并且我想从 Address
table 不接触用户。但是我不能。
如果我去掉User
,在这种情况下Address
就去掉了,这样就好了。
但是如何在不触及 User
的情况下删除 Address
?
https://github.com/myTestPercon/TestCascade
User.Java
@Entity
@Table(name = "user", schema = "testCascade")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
private Address address;
// Getter and Setter ...
}
Address.java
@Entity
@Table(name = "address", schema = "testCascade")
public class Address implements Serializable {
@Id
private Long id;
@Column(name = "city")
private String city;
@OneToOne
@MapsId
@JoinColumn(name = "id")
private User user;
// Getter and Setter ...
}
DeleteController.java
@Controller
public class DeleteController {
@Autowired
ServiceJpa serviceJpa;
@GetMapping(value = "/deleteAddressById")
public String deleteAddressById () {
serviceJpa.deleteAddressById(4L);
return "redirect:/home";
}
}
public class Address {
@Id
private Long id;
@MapsId
@JoinColumn(name = "id")
private User user;
}
将 @JoinColumn(name = "id")
重命名为 @JoinColumn(name = "user_id")
你不能说指向用户的列就是地址的 ID
你的映射有误,这就是问题所在。
试试下面的方法看看
User.java
@Entity
@Table(name = "user", schema = "testCascade")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name="foriegn key column in user table for address example.. address_id")
private Address address;
// Getter and Setter ...
}
Address.java
@Entity
@Table(name = "address", schema = "testCascade")
public class Address implements Serializable {
@Id
private Long id;
@Column(name = "city")
private String city;
//name of the address variable in your user class
@OneToOne(mappedBy="address",
cascade={CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH})
private User user;
// Getter and Setter ...
}
为了解决这个问题,需要阅读hibernate Documentation Hibernate Example 162
, Example 163
, Example 164
.
我还建议看看这个
这帮助我解决了这个问题。
而且你还需要指定参数orphanRemoval = true
User.java
@Entity(name = "User")
@Table(name = "user", schema = "testother")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private Address address;
public void addAddress(Address address) {
address.setUser( this );
this.address = address;
}
public void removeAddress() {
if ( address != null ) {
address.setUser( null );
this.address = null;
}
}
// Getter and Setter
}
Address.java
@Entity(name = "Address")
@Table(name = "address", schema = "testother")
public class Address implements Serializable {
@Id
private Long id;
@Column(name = "city")
private String city;
@OneToOne
@MapsId
@JoinColumn(name = "id")
private User user;
// Getter and Setter
}
删除控制器。java
@Controller
public class DeleteController {
@Autowired
ServiceJpa serviceJpa;
@GetMapping(value = "/deleteUser")
public String deleteUser () {
User user = serviceJpa.findUserById(2L).get();
user.removeAddress();
serviceJpa.saveUser(user);
return "/deleteUser";
}
}
或自定义 SQL 查询。
@Repository
public interface DeleteAddress extends JpaRepository<Address, Long> {
@Modifying
@Query("delete from Address b where b.id=:id")
void deleteBooks(@Param("id") Long id);
}