代码之家  ›  专栏  ›  技术社区  ›  Alex

完整性约束冲突:外键HSQL上的唯一约束或索引冲突

  •  2
  • Alex  · 技术社区  · 8 年前

    我正在使用Hibernate/Spring Boot测试HSQL数据库的底层模型,遇到了一个无法找到解决方案的问题。

    这是我的简单测试,我试图创建一个鞋盒实体,并将其保存到数据库中,其中用户对象设置为所有者的FK:

    @TestConfiguration
    static class ShoeboxServiceTestContextConfiguration {
    
        @Bean
        public ShoeboxService shoeboxService() {
            return new ShoeboxService();
        }
    
        @Bean
        public UserService userService() {
            return new UserService();
        }
    }
    
    @Autowired
    UserService users;
    
    @Autowired
    ShoeboxService shoeboxes;
    
    @Test
    public void testSave()
    {
        System.out.println("save");
        int userId = 1;
        User user = new User(userId, "Foo", "hello@world.com");
    
        user = users.save(user);
    
        Shoebox sb = new Shoebox(user, "Name", "Context", "Comment", false);
        UUID sbId = shoeboxes.save(sb).getId();
    
        sb = shoeboxes.findOne(sbId);
        assertNotNull(sb);
        assertEquals(sb.getName(), "Name");
        assertEquals(sb.getContext(), "Context");
        assertEquals(sb.getComment(), "Comment");
        assertEquals(sb.isShare(), false);
    
        shoeboxes.deleteById(sbId);
        users.deleteById(userId);
    }
    

    然而,当它得到它抛出一个

    完整性约束冲突:唯一约束或索引冲突;SYS\U PK\U 10126表格:用户

    尝试将鞋盒保存到DB时出现异常。它成功地持久化了用户,并且在没有所有者FK连接到鞋盒对象时,它成功地持久化了鞋盒对象,但在提供FK时崩溃。

    以下是我的用户POJO:

    @Entity
    @Table(name="User")
    @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
    public class User implements Serializable
    {
    
        @Id
        @Column(name = "ID")
        private long ID;
    
        @Column(name = "Name")
        private String name;
    
        @Column(name = "Email")
        private String email;
    
        @OneToOne(fetch = FetchType.LAZY)
        private Shoebox currentlySelectedBox;
    
        @OneToMany(fetch = FetchType.LAZY)
        @JsonManagedReference(value="shoebox_owner")
        private List<Shoebox> shoeboxes;
    
        // Contructors, Getters/Setters etc.
    }
    

    还有我的鞋盒POJO:

    @Entity
    @Table(name="Shoebox")
    @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
    public class Shoebox implements Serializable
    {
        @Id
        @Column(name="ID")
        UUID ID;
    
        @ManyToOne(cascade = CascadeType.ALL)
        @JoinColumn(name="OwnerID")
        @JsonBackReference(value="shoebox_owner")
        User owner;
    
        @Column(name="Name")
        String name;
    
        @Column(name="Context")
        String context;
    
        @Column(name="Comment")
        String comment;
    
        @Column(name="Shared")
        boolean share;
    
        @Column(name="CreationDate")
        LocalDateTime creationDate;
    
        // Contructors, Getters/Setters etc.
    }
    

    以下是DB的HSQL创建脚本:

    CREATE MEMORY TABLE PUBLIC.SHOEBOX(ID BINARY(255) NOT NULL PRIMARY KEY,COMMENT VARCHAR(255),CONTEXT VARCHAR(255),CREATIONDATE TIMESTAMP,NAME VARCHAR(255),SHARED BOOLEAN,OWNERID BIGINT)
    CREATE MEMORY TABLE PUBLIC.USER(ID BIGINT NOT NULL PRIMARY KEY,EMAIL VARCHAR(255),NAME VARCHAR(255),CURRENTLYSELECTEDBOX_ID BINARY(255),CONSTRAINT FK3T924ODM2BIK5543K0E3UEGP FOREIGN KEY(CURRENTLYSELECTEDBOX_ID) REFERENCES PUBLIC.SHOEBOX(ID))
    CREATE MEMORY TABLE PUBLIC.USER_SHOEBOX(USER_ID BIGINT NOT NULL,SHOEBOXES_ID BINARY(255) NOT NULL,CONSTRAINT FK5W8WMFC5E9RMEK7VC4N76MQVQ FOREIGN KEY(SHOEBOXES_ID) REFERENCES PUBLIC.SHOEBOX(ID),CONSTRAINT FKIR9SOKRCOQ33LCQTNR0LDXO93 FOREIGN KEY(USER_ID) REFERENCES PUBLIC.SHOEBOXUSER(ID),CONSTRAINT UK_508XA86IDIHP04FQD3D6GF8D7 UNIQUE(SHOEBOXES_ID))
    ALTER TABLE PUBLIC.SHOEBOX ADD CONSTRAINT FK3J9RQBYW5VQ0IRF3FWYPG7LAB FOREIGN KEY(OWNERID) REFERENCES PUBLIC.USER(ID)
    

    为什么会触发异常?我的注释和对象之间的PK/FK关系是否有问题?

    非常感谢。

    1 回复  |  直到 8 年前
        1
  •  2
  •   secondbreakfast    8 年前

    问题是

    @ManyToOne(cascade = CascadeType.ALL)

    具有 CascadeType.ALL ,任何操作都将扩展到其他实体。因此,在这种情况下,save方法会层叠在鞋盒的用户上,试图再次保存它。因为您使用的静态id为 1 ,它会导致关键点约束。