代码之家  ›  专栏  ›  技术社区  ›  Felipe S.

Spring Hibernate-@不同事务之间的事务

  •  0
  • Felipe S.  · 技术社区  · 5 年前

    我正在创建一个测试,基本上在 @Transactional 方法。

    我加了一个 Project ,然后添加 Task 最后将再次从数据库中获取项目,以测试是否保存了任务。

    请注意,我所展示的情况是一个单元测试,但我更感兴趣的是固定事务方法,而不是测试本身,正如我以前在“生产代码”中已经拥有的那样。

    模型类:

    @Entity
    @Table(name = "Task")
    data class Task(
            @Id
            @SequenceGenerator(name = "TaskSeq", sequenceName = "TaskSeq", initialValue = 100)
            @GeneratedValue(generator = "TaskSeq")
            val id: Long = 0,
    
            @Column(nullable = false)
            val name: String,
    
            val description: String,
    
            val inZ: LocalDateTime = LocalDateTime.now(),
            var outZ: LocalDateTime = JpaConstants.MAX_DATETIME,
            var completed: Boolean = false,
    
            @ManyToOne(cascade = [CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH])
            @JoinColumn(name = "projectId")
            var project: Project? = null
    ) {
    }
    
    @Entity
    @Table(name = "Project")
    data class Project(
            @Id
            @SequenceGenerator(name = "ProjectSeq", sequenceName = "ProjectSeq", initialValue = 100)
            @GeneratedValue(generator = "ProjectSeq")
            val id: Long = 0,
    
            @Column(nullable = false)
            var name: String,
    
            @OneToMany(mappedBy = "project", cascade = [CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH])
            val tasks: MutableList<Task> = Lists.mutable.empty()
    ) {
    
    }
    

    服务类别:

    @Service
    class ProjectServiceImpl(private val projectRepository: ProjectRepository) : ProjectService {
    
        override fun save(project: Project): Project {
            return projectRepository.save(project)
        }
    
    }
    
    
    @Service
    class TaskServiceImpl(private val taskRepository: TaskRepository, private val projectRepository: ProjectRepository) : TaskService {
    
    
        override fun save(task: Task): Task {
            return taskRepository.save(task)
        }
    
        override fun addTaskToProject(projectId: Long, task: Task): Task {
            val project = projectRepository.findById(projectId).orElseThrow { RecordNotFoundException("Couldn't find project with id {$projectId}") }
            task.project = project
    
            return save(task)
        }
    }
    

    我试图使用事务方法的类:

    class TaskServiceImplTest : TaskApplicationTests() {
    
    @Autowired
    private lateinit var taskService: TaskService
    
    @Autowired
    private lateinit var taskRepository: TaskRepository
    
    @Autowired
    private lateinit var projectService: ProjectService
    
    
    @Test
    @Transactional
    fun canInsertTaskToProject() {
        val project = projectService.save(Project(name = "Conquer Paris"))
        var task = Task(name = "Check how many people we need to hire", description = "")
        task = taskService.addTaskToProject(project.id, task)
    
        assertTrue(task.id > 0)
        val projects = projectService.findAll()
        assertEquals(1, projects.size())
        assertEquals(1, projects[0].tasks.size)
        assertEquals(task.id, projects[0].tasks[0].id)
    }
    

    如果我加一个 @Transactional(REQUIRES_NEW) 对于服务中的方法,它将起作用,但我不希望它好像是在真正的事务中调用的,我希望它相应地回滚另外,我想避免使用太多的新需求以避免将来出现问题

    如果我移除 @事务性 从测试方法来看,当我在最后两行测试任务列表的大小时,它将不起作用,因为它们很懒。

    什么是让它工作的最好方法我以为里面 @事务性 当我使用来自db的另一个命令时,它将获得尚未提交的最新更新。。

    如果需要,Java中的代码也可以:)

    提前谢谢!

    0 回复  |  直到 5 年前
        1
  •  1
  •   Jonathan JOhx    5 年前

    根据您的场景,您可以使用 @TestEntityManager 以便可以在事务上下文中管理每个测试。 这个例子可以帮助你,

    https://grokonez.com/testing/datajpatest-with-spring-boot