JPA:我看不到添加的实体

时间:2016-06-20 09:56:35

标签: java hibernate jpa

我使用JPA + Hibernate + Spring来完成简单的工作。 我写了下一个模块:

服务:

@Autowired
private VolMng volMng;

@Service
public class Dist {

@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public void gen() {
        MeterLog mLog = em.find(MeterLog.class, 3625190);
        Lst volTp = lstMng.findByCD("Fact Vol");
        Vol vol = new Vol((MeterLog) mLog, volTp, 7777.77d);
        volMng.add(vol);
        //point-1:
        for (Vol a : mLog.getVol()) {
            System.out.println("found="+a.getId()+" vol="+a.getVol1());
        }
...
...

服务:

@Service
public class VolMngImpl implements VolMng {

    @Autowired
    private VolDAO vDao;

    public void add(Vol vol) {
        vDao.add(vol);
    }

}

DAO:

@Repository
public class VolDAOImpl implements VolDAO {

    @PersistenceContext
    private EntityManager em;

    public void add(Vol vol) {
        em.persist(vol);
    }

}

我正在尝试将一些记录添加到子实体Vol。

但是在第1点的volMng.add(vol)之后,我没有看到任何添加的记录(子实体)。 为什么?

UPD

当然我在交易结束后会看到这些记录,但为什么我不能在之前做到?它们必须在内存缓存中......

upd2

我的spring.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd">

    <!-- *******************************
         ***** CACHE CONFIGURATION ***** 
         ******************************* -->                
    <cache:annotation-driven  cache-manager="cacheManager" />

    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager" ref="ehcache"/>
    </bean>
    <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:ehcache.xml"/>
        <property name="shared" value="true"/>
    </bean>    

    <bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close"> 
          <property name="URL" value="jdbc:oracle:thin:@192.168.1.1:1521:DEV" /> 
          <property name="user" value="ora"/> 
          <property name="password" value="ora"/> 
          <property name="connectionCachingEnabled" value="true"/> 
    </bean>

    <bean
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        id="entityManagerFactory">
        <property name="dataSource" ref="dataSource" />
    </bean>

     <context:component-scan base-package="com.ric.bill" />
     <context:component-scan base-package="com.ric.bill.dao.impl" />
     <context:component-scan base-package="com.ric.bill.mm.impl" />


    <bean class="org.springframework.orm.jpa.JpaTransactionManager"
        id="transactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

 <tx:annotation-driven mode="proxy" transaction-manager="transactionManager"/>



    <context:spring-configured />
    <context:annotation-config />


</beans>

3 个答案:

答案 0 :(得分:1)

收藏不会在会话中自动更新。 一旦您重新加载所有内容,它就会出现,但您必须手动将其添加到拥有对象的子集合中,以防您在当前会话中需要它。

答案 1 :(得分:0)

要解决这个问题,我必须将子实体添加到父级,如下所示:

    MeterLog mLog = em.find(MeterLog.class, 3625190);
    Lst volTp = lstMng.findByCD("Fact Vol");
    Vol vol = new Vol((MeterLog) mLog, volTp, 7777.77d);
    mLog.getVol().add(vol);
    //point-1:
    for (Vol a : mLog.getVol()) {
        System.out.println("found="+a.getId()+" vol="+a.getVol1());
    }

答案 2 :(得分:0)

要回答实际问题 - 为什么你看不到新添加的实体......

运行select语句并将结果放在java对象中:

MeterLog mLog = em.find(MeterLog.class, 3625190);

find最终创建select语句,并根据您用来定义映射的jpa注释,通过hibernate将结果集转换为MeterLog对象。从这一点开始,您的代码不会更改此对象。您可以使用以下代码创建新实体:

volMng.add(vol);

直接将新实体持久保存在数据库中。但是,这是在select已经返回您要求的数据之后。您没有做任何事情来更改或刷新您已经获得的结果集。底层数据存储区(oracle,mysql,无论如何)都不记得你已查询过它并且正在保存其数据的副本,因此它无法提醒您基础数据已更改的事实

正如您在答案中提到的,您可以将新实体直接添加到对象的集合中:

mLog.getVol().add(vol);

在某些情况下,这将在事务成功完成时将新实体持久保存到数据库中,但也允许您在循环访问集合时查看实体,从而观察您的实体。然而,你已经违反了德米特的法则 - 在创建时,将自己添加到给定MeterLog的卷集合中应该是Vol的责任。