春季休眠 - 在不同事务之间@Transactional



我正在创建一个测试,基本上在@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),它将起作用,但我不希望它好像在真实事务中调用此方法一样,我希望它相应地回滚。我也想避免使用太多REQUIRES_NEW以避免将来出现问题

如果我从测试方法中删除@Transactional,当我在最后两行测试任务列表的大小时,它不起作用,因为它们很懒惰。

让它工作的最佳方法是什么?我以为在@Transactional内,当我使用数据库的另一个命令时,它会获得尚未提交的最新更新。

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

提前感谢!

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

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

最新更新