2009-11-22 3 views
2

Comment puis-je configurer une relation OneToMany de base à l'aide d'une liste et obtenir JPA Hibernate pour gérer automatiquement le numéro d'index de séquence de la liste? Cela peut-il être fait?Comment obtenir Hibernate JPA pour gérer l'index de liste automatiquement?

Ceci est mon cas de test (plus ou moins);

@Table(name="Policy_Root") 
public class PolicyRoot extends BaseDomainModel { 

    private List<Policy> policyList = new ArrayList<Policy>(); 

    @OneToMany(targetEntity=Policy.class, mappedBy="policyRoot", cascade=CascadeType.ALL) 
    @IndexColumn(name="policy_sequence", base=0, nullable=false) 
    public List<Policy> getPolicyList() { 
     return policyList; 
    } 

    public void setPolicyList(List<Policy> policyList) { 
     this.policyList = policyList; 
    } 

    public void addPolicy(Policy policy) { 
     policyList.add(policy); 
     policy.setPolicyRoot(this); 
    } 

    public void addPolicy(int sequence, Policy policy) { 
     policyList.add(sequence, policy); 
     policy.setPolicyRoot(this); 
    } 
} 

@Entity() 
@Table(name="Policy") 
public class Policy extends BaseDomainModel { 

    /** The position of this policy record within the list of policy's belong to the parent PolicyRoot */ 
    private int policySequence; 

    /** Birectional pointer to parent */ 
    private PolicyRoot policyRoot; 

    @Column(name="policy_sequence") 
    public int getPolicySequence() { 
     return policySequence; 
    } 

    public void setPolicySequence(int policySequence) { 
     this.policySequence = policySequence; 
    } 

    @ManyToOne 
    @JoinColumn(name="policy_root_oid", nullable=false) 
    public PolicyRoot getPolicyRoot() { 
     return policyRoot; 
    } 

    public void setPolicyRoot(PolicyRoot policyRoot) { 
     this.policyRoot = policyRoot; 
    } 
} 


    @Test 
    public void testCreation() { 
     Policy policy1 = new Policy(); 
     Policy policy2 = new Policy(); 

     // Uncomment the following and the test case works - but I don't want to manage the sequence numbers 
     //policy2.setPolicySequence(1); 

     PolicyRoot policyRoot = new PolicyRoot(); 
     policyRoot.addPolicy(policy1); 
     policyRoot.addPolicy(policy2); 

     ServiceImplFacade.getPersistenceFacade().persistSingleItem(policyRoot); 
     Long oid = policyRoot.getOid(); 
     PolicyRoot policyRootFromDB = ServiceImplFacade.getPersistenceFacade().getEntityManager().find(PolicyRoot.class, oid); 

     assertEquals(2, policyRootFromDB.getPolicyList().size()); 
    } 

Si je décommente le policy2.setPolicySequence (1); ligne puis le cas de test passe, mais je ne pense pas que je dois faire cela. Je veux que Hibernate fasse ça pour moi. Je crois comprendre que c'est possible, mais si elle ne le peut pas, sachant que cela ne peut pas être une bonne réponse.

J'ai essayé différentes combinaisons de réglages nullables, insérables et modifiables, mais j'en ai peut-être manqué une.

Est-ce possible? - Si c'est le cas, comment?

Répondre

2

J'ai trouvé la réponse, - c'était de trouver les bonnes combinaisons de nullable et insérable. A également dû faire le "index enfant" à Integer afin qu'il puisse être nullable, et il y a aussi un drapeau "facultatif" dans le suivant également.

public class PolicyRoot extends BordereauxBaseDomainModel { 

    private List<Policy> policyList = new ArrayList<Policy>(); 

    @OneToMany(cascade=CascadeType.ALL) 
    @IndexColumn(name="policy_sequence", nullable=false, base=0) 
    @JoinColumn(name="policy_root_oid", nullable=false) 
    public List<Policy> getPolicyList() { 
     return policyList; 
    } 

    public void setPolicyList(List<Policy> policyList) { 
     this.policyList = policyList; 
    } 
} 


public class Policy extends BordereauxBaseDomainModel { 

    /** The position of this policy record within the list of policy's belong to the parent PolicyRoot */ 
    private Integer policySequence; 

    /** Birectional pointer to parent */ 
    private PolicyRoot policyRoot; 

    @Column(name="policy_sequence", insertable=false, updatable=false) 
    public Integer getPolicySequence() { 
     return policySequence; 
    } 

    public void setPolicySequence(Integer policySequence) { 
     this.policySequence = policySequence; 
    } 

    @ManyToOne(optional=false) 
    @JoinColumn(name="policy_root_oid", insertable=false, updatable=false, nullable=false) 
    public PolicyRoot getPolicyRoot() { 
     return policyRoot; 
    } 

    public void setPolicyRoot(PolicyRoot policyRoot) { 
     this.policyRoot = policyRoot; 
    } 
} 

Vous avez trouvé les réponses à la page suivante après une recherche sur Google pendant un certain temps.

http://opensource.atlassian.com/projects/hibernate/browse/HHH-4390

0

quelque chose comme ça:

@Entity 
class Parent { 

    @OneToMany 
    @IndexColumn(name = "index_column") 
    List<Child> children; 
} 

@Entity 
class Child { 

    @ManyToOne 
    Parent parent; 
    @Column(name = "index_column") 
    Integer index; 

    @PrePersist 
    @PreUpdate 
    private void prepareIndex() { 
     if (parent != null) { 
      index = parent.children.indexOf(this); 
     } 
    } 
} 
+2

Soyez prudent lors de l'affichage copier et coller/réponses boilerplate in extenso à plusieurs questions, celles-ci ont tendance à être marqués comme « spammy » par la communauté. Si vous faites cela, cela signifie généralement que les questions sont des doublons, alors signalez-les comme tels: http://stackoverflow.com/a/12484278/419 – Kev

Questions connexes