【发布时间】:2022-01-26 16:39:03
【问题描述】:
当我使用 hibernate 时,一旦我进行了测试,所做的所有更改都会在这些测试完成后回滚。
但是当我将 JDBC 与我的 DAO 实现而不是 JpaRepositories 一起使用时,测试期间发生的突变不会被回滚。
我怎样才能让所有更改都被回滚?
在这里你可以看到我的一个测试类的样子:
package com.cemonan.bookdb2;
import com.cemonan.bookdb2.dao.BookDao;
import com.cemonan.bookdb2.domain.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.ComponentScan;
import java.util.List;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ComponentScan(basePackages = {"com.cemonan.bookdb2.dao"})
public class BookDaoIntegrationTest {
@Autowired
BookDao bookDao;
@Test
void testCreateBook() {
List<Book> books = bookDao.findAll();
int countBefore = books.size();
Book book = new Book();
book.setTitle("A book");
book.setIsbn("123");
book.setPublisher("Someone");
Book savedBook = bookDao.save(book);
books = bookDao.findAll();
int countAfter = books.size();
assertThat(savedBook).isNotNull();
assertThat(countAfter).isGreaterThan(countBefore);
}
}
package com.cemonan.bookdb2.dao;
import com.cemonan.bookdb2.domain.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import static com.cemonan.bookdb2.dao.utils.Utils.closeAll;
@Component
public class BookDaoImpl implements BookDao {
@Autowired
DataSource source;
Book mapRsToBook(ResultSet rs) throws SQLException {
Book book = new Book();
book.setId(rs.getLong("id"));
book.setTitle(rs.getString("title"));
book.setIsbn(rs.getString("isbn"));
book.setPublisher(rs.getString("publisher"));
return book;
}
@Override
public Book findById(Long id) {
Connection connection = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
connection = this.source.getConnection();
ps = connection.prepareStatement("SELECT * FROM book WHERE id = ?");
ps.setLong(1, id);
rs = ps.executeQuery();
if (rs.next()) {
return mapRsToBook(rs);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
closeAll(rs, ps, connection);
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
@Override
public Book save(Book book) {
Connection connection = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
connection = this.source.getConnection();
ps = connection.prepareStatement("INSERT INTO book (title, isbn, publisher) VALUES (?, ?, ?)");
ps.setString(1, book.getTitle());
ps.setString(2, book.getIsbn());
ps.setString(3, book.getPublisher());
ps.execute();
Statement stmt = connection.createStatement();
rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");
if (rs.next()) {
return this.findById(rs.getLong(1));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
closeAll(rs, ps, connection);
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
@Override
public Book update(Book book) {
Connection connection = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
connection = this.source.getConnection();
ps = connection.prepareStatement("UPDATE book SET title = ?, isbn = ?, publisher = ? WHERE id = ?");
ps.setString(1, book.getTitle());
ps.setString(2, book.getIsbn());
ps.setString(3, book.getPublisher());
ps.setLong(4, book.getId());
ps.execute();
if (rs.next()) {
return this.findById(book.getId());
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
closeAll(rs, ps, connection);
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
@Override
public void delete(Book book) {
Connection connection = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
connection = this.source.getConnection();
ps = connection.prepareStatement("DELETE FROM book WHERE id = ?");
ps.setLong(1, book.getId());
ps.execute();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
closeAll(rs, ps, connection);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
@Override
public Book findByTitle(String title) {
Connection connection = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
connection = this.source.getConnection();
ps = connection.prepareStatement("SELECT * FROM book WHERE title = ?");
ps.setString(1, title);
rs = ps.executeQuery();
if (rs.next()) {
return this.mapRsToBook(rs);
}
} catch(SQLException e) {
e.printStackTrace();
} finally {
try {
closeAll(rs, ps, connection);
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
@Override
public List<Book> findAll() {
Connection connection = null;
Statement stmt = null;
ResultSet rs = null;
List<Book> books = new ArrayList<>();
try {
connection = this.source.getConnection();
stmt = connection.createStatement();
rs = stmt.executeQuery("SELECT * FROM book");
while(rs.next()) {
Book book = this.mapRsToBook(rs);
books.add(book);
}
} catch(SQLException e) {
e.printStackTrace();
} finally {
try {
closeAll(rs, stmt, connection);
} catch (SQLException e) {
e.printStackTrace();
}
}
return books;
}
}
【问题讨论】:
-
您能出示您的
BookDao代码吗? -
@fladdimir 我已将其添加到问题中。
-
您不应该让 BookDao 事务性以使事情回滚吗?
-
请修剪您的代码,以便更容易找到您的问题。请按照以下指南创建minimal reproducible example。
标签: java spring hibernate jpa jdbc