# Selbstreferenzierter Entity-Bean



## akira (27. Mrz 2007)

Hallo zusammen,

ich versuche mich zur Zeit etwas in den Java Application Server 9 einzuarbeiten und bin auf ein Problem mit einem selbstreferenzierten Entity-Bean gestoßen. 

Ich habe eine Entity GroupEntity, die für eine Benutzergruppe stehen soll. Das Bean hat einen zusammengesetzen Key aus der Group-Id und einer Domain-Id, zu der die Gruppe gehört. Zusätzlich kann eine Gruppe auch eine Vater-Gruppe haben oder selbst Vater mehrere Untergruppen sein.

Hier erstmal der Code, zuerst der Key, dann der Bean


```
public class GroupKey implements Serializable {
    
    private Long domainId;
    
    private Long groupId;
    
    public GroupKey() {
    }

    public Long getDomainId() {
        return domainId;
    }

    public void setDomainId(Long domainId) {
        this.domainId = domainId;
    }

    public Long getGroupId() {
        return groupId;
    }

    public void setGroupId(Long groupId) {
        this.groupId = groupId;
    }
}
```



```
@IdClass(esp.ums.entities.key.GroupKey.class)
@Entity
@Table(name = "ESP_UMS_GROUP")
public class GroupEntity implements Group, Serializable {

    private DomainEntity domainEntity;
    
    private GroupEntity parentEntity;
    
    private Collection<GroupEntity> children;
    
    private Long domainId;
    
    private Long groupId;
    
    private String groupName;
    
    private String description;
    
    public GroupEntity() {
    }
    
    public GroupEntity(Group group) {
        if(group!=null)
            BeanHelper.copy(group, this, Group.class);
    }
    
    @Transient
    public GroupBean getBean() {
        return new GroupBean(this);
    }
    
    @Id
    @Column(name="GROUP_ID")
    @GeneratedValue(strategy = GenerationType.TABLE, generator="GROUP_TAB")
    public Long getGroupId() {
        return groupId;
    }

    public void setGroupId(Long groupId) {
        this.groupId = groupId;
    }
    
    @Id
    @Column(name = "DOMAIN_ID", nullable = false, insertable = false, updatable = false)
    public Long getDomainId() {
        return domainId;
    }
    
    @Transient
    public Domain getDomain() {
        return getDomainEntity().getBean();
    }
    
    public void setDomain(Domain domain) {}

    public void setDomainId(Long domainId) {
        this.domainId = domainId;
    }

    @ManyToOne
    @JoinColumn(name = "DOMAIN_ID")
    public DomainEntity getDomainEntity() {
        return domainEntity;
    }

    public void setDomainEntity(DomainEntity domainEntity) {
        this.domainEntity = domainEntity;
    }
    
    
    public String getGroupName() {
        return groupName;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
    
    @ManyToOne
    @JoinColumns({
        @JoinColumn(name = "PARENT_GROUP_ID",referencedColumnName = "GROUP_ID")
        , @JoinColumn(name = "PARENT_DOMAIN_ID", referencedColumnName = "DOMAIN_ID")
    })
    public GroupEntity getParentEntity() {
        return parentEntity;
    }
    
    public void setParentEntity(GroupEntity parent) {
        this.parentEntity = parent;
    }
    
}
```

Beim deployen bekomme ich folgende Fehler:



> JDO76609: Got SQLException executing statement "ALTER TABLE ESP_UMS_GROUP ADD CONSTRAINT SPMSGRUPPRNTGRUPID FOREIGN KEY (PARENT_GROUP_ID) REFERENCES ESP_UMS_GROUP (GROUP_ID)": org.apache.derby.client.am.SqlException: Constraint 'SPMSGRUPPRNTGRUPID' is invalid: there is no unique or primary key constraint on table 'ESP.ESP_UMS_GROUP' that matches the number and types of the columns in the foreign key.
> JDO76609: Got SQLException executing statement "ALTER TABLE ESP_UMS_GROUP ADD CONSTRAINT SPMSGRPPRNTDMAINID FOREIGN KEY (PARENT_DOMAIN_ID) REFERENCES ESP_UMS_GROUP (DOMAIN_ID)": org.apache.derby.client.am.SqlException: Constraint 'SPMSGRPPRNTDMAINID' is invalid: there is no unique or primary key constraint on table 'ESP.ESP_UMS_GROUP' that matches the number and types of the columns in the foreign key.



Ich wolte die Parent-Id eigentlich nicht in den Key mit aufnehmen, da es auch eine root-Gruppe ohne Vater möglich sein soll.

Hat vielleicht jemand eine Idee wie ich das realisieren kann oder was falsch ist? Laut einem Tutorial sollte es eigentlich so gehen.

mfg


----------



## Guest (27. Mrz 2007)

Eine Lösung habe ich auch nicht, aber wenn kein zwingender Grund vorliegt, auf den zusammengesetzten
Primary-Key zu verzichten, würde ich es wie folgt machen. Über Named-Queries kommst du viel einfacher
an die Top-Level-Gruppen heran.
(auf Constraints wie nullable, updatable etc. habe ich hier bewusst verzichtet, damit es nicht ablenkt)

```
@Entity
public class Domain implements Serializable
{
   private static final long serialVersionUID = ...;

   @Id
   @Column( name = "ID" )
   private Long id = null;

   @OneToMany( mappedBy = "domain" )
   private Set<Group> groups = new HashSet<Group>();

   ... Konstruktor(en), Getter/Setter und sonstige Felder
}

@Entity
@NamedQueries(
  {
    @NamedQuery(
      name  = "TopLevelGroupsByDomain",
      query = "from Group g where g.domain.id = :domainId and g.parent is null"
    )
  }
)
public class Group implements Serializable
{
   private static final long serialVersionUID = ...;

   @Id
   @Column( name = "ID" )
   private Long id = null;

   @ManyToOne( optional = false )
   @JoinColumn( name = "DOMAIN_ID" )
   private Domain domain = null;

   @ManyToOne( optional = true )
   @JoinColumn( name = "PARENT_ID" )
   private Group parent = null;

   @OneToMany( mappedBy = "parent" )
   private Set<Group> children = new HashSet<Group>();

   ... Konstruktor(en), Getter/Setter und sonstige Felder
}
```


----------



## Guest (28. Mrz 2007)

Vielen Dank für den Tip mit den Named-Queries, werde ich nachher gleich mal probieren.


----------



## akira (29. Mrz 2007)

Ich bins nochmal, diesmal angemeldet  

Ich habe jetzt mal das Beispielprojekt aus dem EE5 Tutorial 

java.sun.com/javaee/5/docs/tutorial/doc/PersistenceEJB2.html#wp82561

deployd und musste feststellen, das dort die gleichen SQL-Exceptions auftreten wie bei mir.  ???:L 

Liegt das an der JavaDB oder ist das Beispiel falsch.?

Ich will eigentlich nur ungerne auf den Key verzichten, hat da jemand eine Lösung?


----------

