Hibernate:奇怪的行为 - 访问表条目所需的另一个会话中的第二个commit()

时间:2015-07-12 12:29:07

标签: hibernate

我有一个抽象类,只提供对会话创建的简单访问:

private Session currentSession = null;
private Transaction currentTransaction = null;

protected void openSession() {
    this.currentSession = HibernateSession.openSession();
}

protected void openSessionWithTransaction() {
    this.currentSession = HibernateSession.openSession();
    this.currentTransaction = this.currentSession.beginTransaction();
}

public void closeSessionWithTransaction() { 
    this.currentTransaction.commit();
    this.currentSession.close();
}

我注意到当我尝试检索条目时

Tool tool = (Tool) this.getSession().get(Tool.class, toolDto.getId());

我必须首先调用commit()(在与之前或之后的事务无关的会话上),即使给定的ID(此处由toolDto.getId() 确实存在< / strong>。我可以在数据库中看到它,但get()不断返回null ,除非我再次呼叫commit()

首先发生这种情况:

HammerDTO hammerDto = toolSetDto.getHammer();
Hammer hammer = null;

if(hammerDto != null) {
    ToolDTO toolDto = hammerDto.getTool();
    ToolDescriptionDTO hammerDescriptionDto = toolDto.getToolDescription(languageDto.getId());
    // Save new tool
    ToolDescriptionDTO toolDescriptionDto = toolDescriptionRepository.save(storeDto, languageDto, toolDto, hammerDescriptionDto);

    HammerRepository hammerRepository = new HammerRepository(this.getSessionId());
    // Merge new tool into list of (in this case) hammers
    hammer = hammerRepository.merge(storeDto, toolDescriptionDto.getToolDto());
}

我正在存储新工具及其说明。 **此部分有效,Tool条目以及ToolDescription条目在此之后出现:

public ToolDescriptionDTO save(StoreDTO storeDto, LanguageDTO languageDto, ToolDTO toolDto, ToolDescriptionDTO toolDescriptionDto) {

    if(toolDto == null) {
        throw new NullArgumentException("toolDto");
    }

    if(toolDescriptionDto == null) {
        throw new NullArgumentException("toolDescriptionDto");
    }

    this.openSessionWithTransaction();

    Tool tool = null;
    ToolDescription toolDescription = null;

    // First try to check if description exists if it does: load it otherwise: create new one

    Long toolDescriptionId = toolDescriptionDto.getId();

    if(toolDescriptionId != null) {
        toolDescription = (ToolDescription) this.getSession().get(ToolDescription.class, toolDescriptionId);
        tool = toolDescription.getTool();
    }

    if(tool == null) {

        Language language = (Language) this.getSession().get(Language.class, languageDto.getId());

        Store store = this.getStore(storeDto.getId());

        tool = new Tool(store);
        ConvertDTO.convertTool(tool, toolDto);

        tool = (Tool) this.getSession().merge(tool);
        toolDescription = new ToolDescription(tool, language);
    }


    ConvertDTO.convertToolDescription(toolDescription, toolDescriptionDto);
    this.getSession().merge(toolDescription);

    toolDescriptionDto = ConvertEntity.convertToolDescription(toolDescription);

    this.closeSessionWithTransaction();

    return toolDescriptionDto;
}

这是停止工作的部分,正如我所料。试图将“ Hammer ”添加到锤子列表中它只能在commit()上与imho完全不相关的调用上完全不相关的调用:

public Hammer merge(ToolStoreDTO toolStoreDto, ToolDTO toolDto) {

    this.openSession();

    Criteria cr = this.getSession().createCriteria(Hammer.class);
    cr.add(Restrictions.eq("toolStore.id", toolStoreDto.getId()));
    cr.add(Restrictions.eq("tool.id", toolDto.getId()));

    @SuppressWarnings("unchecked")
    List<Hammer> hammers = cr.list();
    Hammer hammer = null;

    // IT ONLY WORKS WITH THIS COMMIT!
    this.getSession().beginTransaction().commit(); // <----- ??

    this.closeSession();

    if(hammers.isEmpty() == false) {
        hammer = hammers.get(0);
    } else {
        ToolStore toolStore = this.getToolStore(toolStoreDto.getId());

        this.openSessionWithTransaction();

        // Always 'null' if the commit above is not executed!
        Tool tool = (Tool) this.getSession().get(Tool.class, toolDto.getId());

        hammer = new Tool(toolStore, tool);
        hammer = (Hammer) this.getSession().merge(tool);

        this.closeSessionWithTransaction();
    }

    return hammer;
}

这对我没有意义。 我已提交(在之前的会话中)并且相应的条目确实存在

这种行为可能是什么原因?

hibernate.cfg.xml中

<hibernate-configuration>
    <session-factory>
        <property name="connection.url">jdbc:mysql://localhost:3306/mahlzeit_db</property>
        <property name="connection.username">root</property>
        <property name="connection.password"></property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">false</property>
        <property name="format_sql">false</property>            
        <!-- Run Hibernate in update mode -->
        <property name="hibernate.hbm2ddl.auto">update</property>
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>
        <property name="current_session_context_class">thread</property>        
        <!-- ... --->
    </session-factory>  
</hibernate-configuration>

0 个答案:

没有答案