Hello.
@OneToMany(fetch = FetchType.LAZY) doesn't work when using EJB or something else related to J2EE. parent.getChildren() returns null. Here is a simple example:
Bean:
@Named("test") @RequestScoped public class TestBean { private String mode; @PersistenceContext(unitName = "my-pu") private EntityManager entityManager; @EJB private Manager manager; private List<Parent> parents; @PostConstruct private void postConstruct() { Query query = entityManager.createQuery("SELECT p FROM Parent p"); parents = query.getResultList(); } public void addParent() { Parent parent = new Parent(); manager.persist(parent); postConstruct(); } public void addChild(Parent parent) { Child child = new Child(); child.setParent(parent); manager.persistChild(child); } public String getMode() { return mode; } public void setMode(String mode) { this.mode = mode; } public List<Parent> getParents() { return parents; } public void setParents(List<Parent> parents) { this.parents = parents; } }
Entities:
@Entity @SequenceGenerator(name = "b", allocationSize = 1) public class Parent { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "b") private int id; @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List<Child> children; public int getId() { return id; } public void setId(int id) { this.id = id; } public List<Child> getChildren() { return children; } public void setChildren(List<Child> children) { this.children = children; } } @Entity @SequenceGenerator(name = "b", allocationSize = 1) public class Child { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "b") private int id; @ManyToOne private Parent parent; public int getId() { return id; } public void setId(int id) { this.id = id; } public Parent getParent() { return parent; } public void setParent(Parent parent) { this.parent = parent; } }
Manager:
@Stateless @TransactionManagement(TransactionManagementType.BEAN) public class Manager { @Resource private UserTransaction transaction; @PersistenceContext(unitName = "my-pu") private EntityManager entityManager; public void persist(Object o) { try { transaction.begin(); entityManager.persist(o); transaction.commit(); } catch (NotSupportedException e) { e.printStackTrace(); } catch (SystemException e) { e.printStackTrace(); } catch (RollbackException e) { e.printStackTrace(); } catch (HeuristicMixedException e) { e.printStackTrace(); } catch (HeuristicRollbackException e) { e.printStackTrace(); } } public void persistChild(Child child) { try { transaction.begin(); entityManager.persist(child); if (child.getParent().getChildren() == null) { child.getParent().setChildren(new ArrayList<Child>()); } child.getParent().getChildren().add(child); entityManager.merge(child.getParent()); transaction.commit(); } catch (NotSupportedException e) { e.printStackTrace(); } catch (SystemException e) { e.printStackTrace(); } catch (RollbackException e) { e.printStackTrace(); } catch (HeuristicMixedException e) { e.printStackTrace(); } catch (HeuristicRollbackException e) { e.printStackTrace(); } } }
JSF:
<f:view> <h:form> <h:commandButton value="Run a method" action="#{test.addParent}"/> </h:form> <ui:repeat value="#{test.parents}" var="p"> #{p.id}<br /> <ui:repeat value="#{p.children}" var="c"> ---#{c.id}<br /> </ui:repeat> <h:form> <h:commandButton value="asdasd" action="#{test.addChild(p)}" /> </h:form> </ui:repeat> <h:messages /> </f:view>