【问题标题】:OneToOne CascadeType in spring data jpa春季数据 jpa 中的 OneToOne CascadeType
【发布时间】:2021-07-04 00:59:24
【问题描述】:

我在 spring data JPA 中使用 OneToOne 并且我想从 Address 表中删除一条记录而不触摸用户。但我做不到。

如果我删除 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 ...


    }

删除控制器.java

    @Controller
    public class DeleteController {


        @Autowired
        ServiceJpa serviceJpa;


        @GetMapping(value = "/deleteAddressById")
        public String deleteAddressById () {


            serviceJpa.deleteAddressById(4L);
            return "redirect:/home";


        }

    }

【问题讨论】:

    标签: spring hibernate spring-data-jpa spring-data hibernate-mapping


    【解决方案1】:
     public class Address {
    
       @Id
        private Long id;      
    
        @MapsId
        @JoinColumn(name = "id")
        private User user;
      }
    

    @JoinColumn(name = "id") 重命名为@JoinColumn(name = "user_id")

    你不能说指向用户的列就是地址的id

    【讨论】:

    • @OneToOne 创建一个额外的列作为外键指向另一个表。所以你说地址表会有额外的列。你命名那个额外的列ID。 Id 必须是指向用户的外键。所以 id 将具有用户 ID 的值。但是您已经在该表中有一个名为 id 的列,该列具有地址 Id。希望你看看这里出了什么问题
    • 我需要一个通用标识符。正如我所指出的那样。我只想在不接触用户的情况下删除地址。如果我进入MySQL数据库并删除地址,地址被删除,用户不受影响。我也想在不接触用户的情况下删除地址。
    • 您的 JPA 配置错误,这就是用户被意外删除的原因。更改我所说的内容并搜索JoinColumn 并阅读以了解其工作原理。然后你就会明白我已经解释了什么
    • 我完全按照你说的做了。情况没有改变。 @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; @Column(name = "name") 私有字符串名称; @OneToOne(mappedBy = "user", cascade = CascadeType.ALL) // ALL 私有地址地址;
    • @zvzvzxvzxv 你现在的地址类别是什么?
    【解决方案2】:

    你的映射错了,这就是问题所在。

    试试下面看看

    用户.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 ...
    
    
    }
    

    地址.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 ...
    
    
    }
    

    【讨论】:

      【解决方案3】:

      为了解决这个问题,需要阅读hibernateDocumentation HibernateExample 162Example 163Example 164 >.

      我也推荐看看这是Using @PrimaryKeyJoinColumn annotation in spring data jpa

      这帮助我解决了这个问题。

      而且还需要指定参数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);
      
          }
      

      【讨论】:

        猜你喜欢
        • 2016-01-30
        • 2013-11-12
        • 2020-02-20
        • 1970-01-01
        • 2017-06-11
        • 1970-01-01
        • 1970-01-01
        • 2020-08-19
        • 1970-01-01
        相关资源
        最近更新 更多