我正在使用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;
}
我还有一个UserService:
@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<User, Integer> {}
控制器和一切正常工作但有时当我试图用我的用户项目更新列表时发生以下错误:
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]
如何摆脱这个错误?
答案 0 :(得分:0)
如果您发布了Item
课程,这会有所帮助。我的猜测是你需要实施equals(Object obj)
&amp; hashCode()
方法,以便您的Set<Item>
不会重复。
答案 1 :(得分:0)
尝试以这种方式实施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;
}
全部使用课程UserKey
,User
,Item
,Category
,LoginProvider
。并尝试将此注释添加到您的项ID:
@Column(unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
在测试之前,请删除所有记录,以确保您的主键是唯一的。