【问题标题】:DataIntegrityViolationException while storing entity存储实体时出现 DataIntegrityViolationException
【发布时间】:2018-09-12 22:32:05
【问题描述】:

我正在使用 Spring Boot 和 MySQL 作为数据库编写简单的 Web 应用程序。代码如下

我有一个实体用户:

@Entity
@IdClass(UserKey.class)
public class User {

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private Set<Item> items;
    private String fullName;
    @Id
    private String principalId;
    @Id
    @Enumerated(EnumType.STRING)
    private LoginProvider loginProvider;
}

我也有一个用户服务:

@Service
public class UserService {

    @Autowired
    UserRepository userRepository;

    public User getCurrentUser() {
        try {
            return (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        } catch (Exception e) {
            return null;
        }
    }

    @Transactional
    public void addItemToUser(Item item) {
        User currentUser = getCurrentUser();
        if (!currentUser.getItems().contains(item)) {
            currentUser.getItems().add(item);
            userRepository.save(currentUser);
        }
    }
}

还有一个控制器:

@Controller
public class UserController {
PostMapping(value = "/addItem/{id}")
    @ResponseStatus(value = HttpStatus.OK)
    public void addItemToUser(Map<String, Object> model, @PathVariable int id) {
        userService.addItemToUser(itemService.getItem(id));
    }
}

这是我的 Item 类:

@Entity
public class Item {

    @Id
    @GeneratedValue
    private int id;
    @Enumerated
    private Category category;


    public Item() {
    }


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Category getCategory() {
        return category;
    }

    public void setCategory(Category category) {
        this.category = category;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        Item item = (Item) o;

        return id == item.id;
    }

    @Override
    public int hashCode() {
        return id;
    }
}

这是我的存储库:

public interface UserRepository extends CrudRepository&lt;User, Integer&gt; {}

控制器和一切工作正常,但有时当我尝试使用我的用户项目更新列表时会出现以下错误:

    2018-04-03 17:09:53.814 ERROR 24265 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [PRIMARY]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '23942983472937-FACEBOOK-2' for key 'PRIMARY'
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_121]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_121]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_121]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_121]
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) ~[mysql-connector-java-5.1.42.jar:5.1.42]
    at com.mysql.jdbc.Util.getInstance(Util.java:408) ~[mysql-connector-java-5.1.42.jar:5.1.42]
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:935) ~[mysql-connector-java-5.1.42.jar:5.1.42]
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973) ~[mysql-connector-java-5.1.42.jar:5.1.42]
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909) ~[mysql-connector-java-5.1.42.jar:5.1.42]
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527) ~[mysql-connector-java-5.1.42.jar:5.1.42]
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680) ~[mysql-connector-java-5.1.42.jar:5.1.42]
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2490) ~[mysql-connector-java-5.1.42.jar:5.1.42]

我怎样才能摆脱这个错误?

【问题讨论】:

    标签: mysql spring-mvc spring-boot spring-data spring-data-jpa


    【解决方案1】:

    如果您发布您的 Item 课程会有所帮助。我的猜测是您需要实现 equals(Object obj)hashCode() 方法,以便您的 Set&lt;Item&gt; 没有重复项。

    【讨论】:

    • 我已经更新了我的问题。 hashCodeequals(Object object) 方法已经实现。也许我做错了?
    【解决方案2】:

    尝试这样实现equals(Object obj)hashCode()

    @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = (prime * result) + (int) id;
            result = (prime * result) + ((category == null) ? 0 : category.hashCode());
    
            return result;
        }
    
    @Override
    public boolean equals(final Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
    
        final Item item = () obj;
        if (id != item.id)
            return false;
        if (!category.equals(item.category))
            return false;
        return true;
    }
    

    使用类 UserKeyUserItemCategoryLoginProvider并尝试将此注释添加到您的项目 ID:

    @Column(unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    

    在测试之前,请删除所有记录,以确保您的主键是唯一的。

    【讨论】:

      猜你喜欢
      • 2021-05-13
      • 1970-01-01
      • 1970-01-01
      • 2014-02-19
      • 2013-10-08
      • 1970-01-01
      • 2016-10-13
      • 1970-01-01
      • 2019-02-18
      相关资源
      最近更新 更多