如何解决如何正确地将元素添加到双向关系?我正在收集被驱逐
我有以下课程
public class User {
@OnetoMany(
fetch = FetchType.EAGER,mappedBy = "user",cascade = CascadeType.ALL
)
private Set<UserSession> sessions;
public UserSession login() {
UserSession session = new UserSession();
session.setUser(this);
session.persistAndFlush();
this.persistAndFlush();
return session;
}
....
public class UserSession {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
protected User user;
如您所见,我正在从它的一侧添加会话。有时有时我会得到
caused by: org.hibernate.HibernateException: collection was evicted
如何正确操作?
解决方法
要添加双向关系中的元素,
- 在父类中创建一个辅助方法来添加或删除子实体。
- 创建子实体并使用辅助方法将其添加到父实体的集合中
- 保存子实体
示例代码:
@Getter
@Setter
@Entity
class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
@OneToMany(mappedBy = "user",cascade = CascadeType.ALL,orphanRemoval = true)
private Set<UserSession> userSessions = new HashSet<>();
public void addNewSession(UserSession userSession) {
this.userSessions.add(userSession);
userSession.setUser(this);
}
public void removeSession(UserSession userSession) {
this.userSessions.remove(userSession);
userSession.setUser(null);
}
}
完整工作代码:
package com.example.demo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;
import org.hibernate.annotations.ResultCheckStyle;
import org.hibernate.annotations.SQLDelete;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.repository.CrudRepository;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@RestController
@RequestMapping("/users")
@EnableTransactionManagement
public class UserAndSessionsController {
private final UserService userService;
@Autowired
public UserAndSessionsController(UserService userService) {
this.userService = userService;
}
@GetMapping
public Iterable<User> list() {
return userService.list();
}
@PostMapping
public User create(@RequestBody User user) {
return userService.save(user);
}
@GetMapping("/sessions")
public Iterable<UserSession> sessions(@RequestParam("userId") Integer userId) {
return userService.getUserSessions(userId);
}
@PostMapping(path = "login")
public UserSession login(@RequestBody User user) throws Throwable {
return userService.createNewLoginSession(user);
}
@PostMapping(path = "logout")
public UserSession logout(@RequestBody UserSessionsDto userSessionsDto) throws Throwable {
return userService.invalidateLoginSession(userSessionsDto.getUser(),userSessionsDto.getUserSession());
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
@ToString
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
class UserSessionsDto {
private User user;
private UserSession userSession;
}
@Getter
@Setter
@Entity
class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
@OneToMany(mappedBy = "user",orphanRemoval = true)
private Set<UserSession> userSessions = new HashSet<>();
public void addNewSession(UserSession userSession) {
this.userSessions.add(userSession);
userSession.setUser(this);
}
public void removeSession(UserSession userSession) {
this.userSessions.remove(userSession);
userSession.setUser(null);
}
}
@Getter
@Setter
@Entity
@SQLDelete(sql = "update USER_SESSION set valid = false where id = ?",check = ResultCheckStyle.COUNT)
class UserSession {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String SessionId;
private boolean valid;
@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY,optional = false)
private User user;
}
@Service
class UserService {
private final UserRepository userRepository;
private final UserSessionRepository userSessionRepository;
@Autowired
UserService(UserRepository userRepository,UserSessionRepository userSessionRepository) {
this.userRepository = userRepository;
this.userSessionRepository = userSessionRepository;
}
@Transactional
public User save(User user) {
return userRepository.save(user);
}
@Transactional(readOnly = true)
public Iterable<User> list() {
return userRepository.findAll();
}
@Transactional(readOnly = true)
public Iterable<UserSession> getUserSessions(Integer userId) {
// return userRepository.findById(userId)
// .map(User::getUserSessions)
// .orElse(Collections.emptySet());
return userSessionRepository.findUserSessionsByUser_Id(userId);
}
@Transactional
public UserSession createNewLoginSession(User user) throws Throwable {
final User dbUser = userRepository
.findById(user.getId())
.orElseThrow(() -> new RuntimeException("User : " + user.getName() + " not found"));
final UserSession userSession = new UserSession();
userSession.setSessionId(UUID.randomUUID().toString());
userSession.setValid(true);
dbUser.addNewSession(userSession);
userSessionRepository.save(userSession);
return userSession;
}
@Transactional
public UserSession invalidateLoginSession(User user,UserSession userSession) throws Throwable {
final User dbUser = userRepository
.findById(user.getId())
.orElseThrow(() -> new RuntimeException("User : " + user.getName() + " not found"));
final UserSession dbUserSession = userSessionRepository
.findById(userSession.getId())
.orElseThrow(() -> new RuntimeException("UserSession : " + userSession.getSessionId() + " not found"));
dbUser.removeSession(dbUserSession);
userSessionRepository.delete(dbUserSession);
return dbUserSession;
}
}
@Repository
interface UserRepository extends CrudRepository<User,Integer> {
}
@Repository
interface UserSessionRepository extends CrudRepository<UserSession,Integer> {
Iterable<UserSession> findUserSessionsByUser_Id(Integer userId);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。