有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案