Java Spring Hibernate@不同事务之间的事务性
我正在创建一个测试,基本上在@Transactional
方法中执行不同的事务
我添加一个Project
,然后向其中添加一个Task
,最后将再次从数据库中获取项目,以测试它是否保存了任务
请注意,我展示的是一个单元测试,但我感兴趣的是修复事务性方法,而不是测试本身,因为我在过去的《生产代码》中已经有过这种情况
模型类:
@Entity
@Table(name = "Task")
public class Task {
@Id
@SequenceGenerator(name = "TaskSeq", sequenceName = "TaskSeq", initialValue = 100)
@GeneratedValue(generator = "TaskSeq")
private Long id;
@Column(nullable = false)
private String name;
private String description;
private LocalDateTime inZ;
private LocalDateTime outZ;
private boolean completed;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name = "projectId")
private Project project;
}
@Entity
@Table(name = "Project")
public class Project {
@Id
@SequenceGenerator(name = "ProjectSeq", sequenceName = "ProjectSeq", initialValue = 100)
@GeneratedValue(generator = "ProjectSeq")
private Long id;
@Column(nullable = false)
private String name;
@OneToMany(mappedBy = "project", cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
private List<Task> tasks;
}
服务类别:
@Service
public class ProjectServiceImpl implements ProjectService {
private final ProjectRepository projectRepository;
@Autowired
public ProjectServiceImpl(ProjectRepository projectRepository) {
this.projectRepository = projectRepository;
}
@Override
public Project save(Project project) {
return projectRepository.save(project);
}
@Override
public List<Project> findAll() {
return projectRepository.findAll();
}
}
@Service
public class TaskServiceImpl implements TaskService {
private TaskRepository taskRepository;
private ProjectRepository projectRepository;
@Autowired
public TaskServiceImpl(TaskRepository taskRepository, ProjectRepository projectRepository) {
this.taskRepository = taskRepository;
this.projectRepository = projectRepository;
}
@Override
@Transactional
public Task addTaskToProject(Long id, Task task) {
Project project = projectRepository.findById(id).orElseThrow(() -> new RuntimeException());
task.setProject(project);
return taskRepository.save(task);
}
}
我尝试使用事务性方法的类:
public class TaskServiceTest extends JavaExampleApplicationTests {
@Autowired
private ProjectService projectService;
@Autowired
private TaskService taskService;
@Test
// @Transactional
public void canInsertTaskToProject() {
Project project = new Project();
project.setName("create company");
project = projectService.save(project);
Task task = new Task();
task.setName("Check how many people we need to hire");
task = taskService.addTaskToProject(project.getId(), task);
assertTrue(task.getId() > 0);
List<Project> projects = projectService.findAll();
assertEquals(1, projects.size());
assertEquals(1, projects.get(0).getTasks().size());
assertEquals(task.getId(), projects.get(0).getTasks().get(0).getId());
}
}
如果我在服务中的方法中添加一个@Transactional(REQUIRES_NEW)
,它将起作用,但我不希望它像在真实事务中调用这个方法一样,我希望它相应地回滚。此外,我希望避免使用太多的REQUIRES_NEW来避免未来的问题
如果我从测试方法中删除@Transactional
,当我在最后两行测试任务列表的大小时,它将不起作用,因为它们是惰性的
如果我在测试方法上添加@Transactional
,它会在最后两行上抛出NullPointerException
,就像我执行projectService.findAll()
任务尚未提交一样
让它工作的最好方法是什么?我以为在一个@Transactional
中,当我使用来自db的另一个命令时,它会得到尚未提交的最新更新
提前谢谢
更新:添加了我从测试中删除@Transactional
的原因
共 (0) 个答案