【问题标题】:Spring + hibernate Pb in loading object with a collection from DBSpring + hibernate Pb 在加载对象时使用来自 DB 的集合
【发布时间】:2015-05-29 22:43:53
【问题描述】:

我有两个像这样的 A 和 B 类

@Entity
@Table
public class A implements Serializable {

@Id
@Column
@GeneratedValue ( strategy = GenerationType.IDENTITY )
private Long                idA;
@Column
private String              nomA;
@OneToMany ( mappedBy = "a" )
private Collection < B >    liste;
..........
}


@Entity
@Table
public class B implements Serializable {

@Id
@Column
@GeneratedValue ( strategy = GenerationType.IDENTITY )
private Long    idB;
@Column
private String  nomB;
@ManyToOne
@JoinColumn ( name = "idA" )
private A       a;
...........
}

这是阿道

@Repository
@Transactional
public class AdaoImpl implements Adao {

@PersistenceContext ( type = PersistenceContextType.EXTENDED )
private EntityManager   em;

@Override
public Long addA ( A a ) {

    em.persist ( a );
    return a.getIdA ( );
}

@Override
public A getA ( Long idA ) {

    return em.find ( A.class , idA );
}

}

这就是B道

@Repository
@Transactional
public class BdaoImpl implements Bdao {

@PersistenceContext ( type = PersistenceContextType.EXTENDED )
private EntityManager   em;

@Override
public Long addB ( B b ) {

    em.persist ( b );
    return b.getIdB ( );
}

@Override
public B getB ( Long idB ) {

    // TODO Auto-generated method stub
    return em.find ( B.class , idB );
}

}

现在是A服务

@Service
@Transactional
public class AserviceImpl implements Aservice {

@Autowired
private Adao    dao;

@Override
public Long ajouterA ( A a ) {

    // TODO Auto-generated method stub
    return dao.addA ( a );
}

@Override
public A retournerA ( Long idA ) {

    // TODO Auto-generated method stub
    return dao.getA ( idA );
}
.......
}

B 服务

@Service
@Transactional
public class BserviceImpl implements Bservice {

@Autowired
private Bdao    dao;

@Override
public Long ajouterB ( B b ) {

    // TODO Auto-generated method stub
    return dao.addB ( b );
}

@Override
public B retournerB ( Long idb ) {

    // TODO Auto-generated method stub
    return dao.getB ( idb );
}
....
}

当我用这段代码测试它时:

ApplicationContext ctx = new ClassPathXmlApplicationContext (
                "spring.xml" );
Aservice aservice = ( Aservice ) ctx.getBean ( "aserviceImpl" );

Bservice bservice = ( Bservice ) ctx.getBean ( "bserviceImpl" );

        A a = new A ( "obj A1" );

        B b1 = new B ( "obj B1" );
        b1.setA ( a );
        B b2 = new B ( "obj B2" );
        b2.setA ( a );
        Long Id = aservice.ajouterA ( a );
        bservice.ajouterB ( b1 );
        bservice.ajouterB ( b2 );

        System.out.println ( ">>>>>>>> "
                + aservice.retournerA ( Id ).toString ( ) );

我得到了 >>>>>>>> A [idA=1, nomA=obj A1, liste=null]

我想知道为什么我的列表是空的

【问题讨论】:

  • 试试@OneToMany ( mappedBy = "a", fetch=FetchType.EAGER)
  • 还是一样的结果

标签: java spring hibernate jpa-2.0 spring-data-jpa


【解决方案1】:

你必须先将 B 项添加到 A 类中的集合中,然后才能保存一个

a.getListe().add(b1);
a.getListe().add(b2);

然后调用

Long Id = aservice.ajouterA ( a );

【讨论】:

    【解决方案2】:

    这样做的原因是休眠一级缓存,也就是会话缓存。它仅在此会话的生命周期内缓存附加到会话的所有实体。

    所以如果你打电话

    em.find ( A.class , idA );
    

    然后休眠将返回缓存的 A,它没有分配 B。

    现在你有两个选择:

    1. 使用

      em.refresh(a);
      

      这样hibernate会从数据库中重新加载a。但是为此,您还需要在与 B 的关系上声明 fetchType.EAGER,正如@HarshPoddar 已经指出的那样。

    2. 将所有 B 添加到 a

      a.getListe().add(b1);
      a.getListe().add(b2);
      

      正如@laugther 已经发布的那样。

    我会选择 2. 选项。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多