Spring,Hibernate:Transactional只读等于true是行不通的

时间:2016-02-18 13:57:32

标签: java spring hibernate spring-mvc transactional

我正在开发一个Spring-MVC项目,我在其中使用注释@Transactional(readOnly=true)调用某些方法。不幸的是,即使这样做,数据库的内容也会更新。不知道怎么做。我究竟做错了什么?我们有一段时间没有这个错误,只是没有知道这是触发数据库中的更改,因为我们完全忽略它,因为注释明确说不要编辑,但我们错了。

项目属性:

<properties>
        <java-version>1.8</java-version>
        <org.springframework-version>4.1.6.RELEASE</org.springframework-version>
        <org.aspectj-version>1.7.4</org.aspectj-version>
        <org.slf4j-version>1.7.5</org.slf4j-version>
        <hibernate.version>4.3.9.Final</hibernate.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <springsecurity.version>4.0.1.RELEASE</springsecurity.version>
        <spring-platform.version>1.1.3.RELEASE</spring-platform.version>
        <jetty.version>9.2.9.v20150224</jetty.version>
    </properties>

    <parent>
        <groupId>io.spring.platform</groupId>
        <artifactId>platform-bom</artifactId>
        <version>1.1.3.RELEASE</version>
        <relativePath />
    </parent>

代码:

     @Override
public byte[] createExcelSheetOutOfCanvas(int canvasId) {
    String str = new BigInteger(130, random).toString(32);

    List<GroupSection> groupSectionList = this.groupSectionService.listGroupSectionByCanvasid(canvasId, false);
    try {
        Workbook workbook = new HSSFWorkbook();
        Sheet sheet = workbook.createSheet();

        int rowCount = 0;
        Row initialRow = sheet.createRow(rowCount);

        writeNames(initialRow);

        for (GroupSection groupSection : groupSectionList) {

            rowCount++;
            Row row = sheet.createRow(++rowCount);

            writeSectionRow(row, groupSection.getMsectionname());

            List<GroupNotes> groupNotesList = this.groupNotesDAO.listGroupNotesBySectionId(groupSection.getMsectionid());
            for (GroupNotes note : groupNotesList) {
                row = sheet.createRow(++rowCount);
                writeBook(note, row);
            }
        }


        try (FileOutputStream outputStream = new FileOutputStream("/home/deploy/excel/" + str + ".xls")) {
            workbook.write(outputStream);

            Path path = Paths.get("/home/deploy/excel/" + str + ".xls");
            return Files.readAllBytes(path);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

GroupSectionServiceImpl:

@Service
@Transactional
public class GroupSectionServiceImpl implements GroupSectionService {

  private final GroupSectionDAO groupSectionDAO;

    @Autowired
    public GroupSectionServiceImpl(GroupSectionDAO groupSectionDAO) {
        this.groupSectionDAO = groupSectionDAO;
    }


 @Override
    @org.springframework.transaction.annotation.Transactional(readOnly = true)
    public List<GroupSection> listGroupSectionByCanvasid(int mcanvasid, boolean masterSectionFlag) {

        List<GroupSection> groupSectionList = this.groupSectionDAO.listGroupSectionByCanvasid(mcanvasid);
// Other method code
}

GroupSectionDAOImpl:

@Repository
@Transactional
public class GroupSectionDAOImpl implements GroupSectionDAO {

    private final SessionFactory sessionFactory;

    @Autowired
    public GroupSectionDAOImpl(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
   @Override
    @Transactional(readOnly = true)
    public List<GroupSection> listGroupSectionByCanvasid(int mcanvasid) {
        Session session = this.sessionFactory.getCurrentSession();
        org.hibernate.Query query = session.createQuery("From GroupSection as msection where " +
                "msection.currentcanvas.mcanvasid=:mcanvasid and msection.sectionDisabled=false and msection.sectionInActive=false");
        query.setParameter("mcanvasid", mcanvasid);
        return query.list();
    }
}

毕竟,即使这个readOnly = true。当我调用createTheExcel方法时,数据库中的值会被覆盖。

控制器方法:

@RequestMapping(value = "/downloadexcel/{canvasid}") 
    public void downloadExcelSheet(@PathVariable("canvasid") int canvasId, HttpServletResponse response) {
        try {
            response.setContentType("application/octet-stream");
            GroupCanvas groupCanvas = this.groupCanvasService.getCanvasById(canvasId);
            if (!(groupCanvas == null)) {
                byte[] excelSheet = this.groupNotesService.createExcelSheetOutOfCanvas(canvasId);
                response.setHeader("Content-Disposition", "attachment; filename=\"" + groupCanvas.getMcanvasname() + ".xls" + "\"");
                response.setContentLength(excelSheet.length);
                FileCopyUtils.copy(excelSheet, response.getOutputStream());
                response.flushBuffer();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2 个答案:

答案 0 :(得分:0)

您的数据库更新与否与readOnly = true无关,而只与您的逻辑有关。 readOnly = true仅供事务管理使用。

答案 1 :(得分:0)

您还必须将createExcelSheetOutOfCanvas设为@Transactional(readOnly = true)