User1230321
User1230321

Reputation: 1475

How to map one to many relationship with itself

I have a table called TERRITORY which has ID, NAME, ID_PARENT_TERRITORY in it. This is in one to many with TERRITORY_WITH_SUBTERRITORIES. Both the columns in TERRITORY_WITH_SUBTERRITORIES are self foreign key to TERRITORY(Self references). This stores rows like this:

TERRITORY: 
ID      NAME        ID_PARENT_TERRITORY
---    ------     ---------------------
1      India        null 
2      Karnataka    1 
3      Bangalore    2
TERRITORY_WITH_SUBTERRITORIES: 
ID_PARENT_TERRITORY      ID_SUBTERRITORY
---------------------    ------------------ 
1                          2 
2                          3 

I'm not able to save data to TERRITORY_WITH_SUBTERRITORIES when data is saved to TERRITORY.

The join table I've written is:

@OneToMany(fetch = FetchType.LAZY, targetEntity = TerritoryDataImpl.class)
@JoinTable(name = "TERRITORY_WITH_SUBTERRITORIES", 
           joinColumns = @JoinColumn(name = "ID_SUBTERRITORY"), 
           inverseJoinColumns = @JoinColumn(name = "id_parent_territory"))        
private List<Territory> childrenStructures = new ArrayList<Territory>();`

After territory collects parentStructure from UI, I've following code to save:

territory.getParentTerritorialStructure().getChildrenStructures().add(object);
    entityManager.merge(territory);

TerritoryDataImpl:

@Entity
@Table(name = "territory")
public class TerritoryDataImpl {

  @Id
  @GeneratedValue
  @Column(name = "id", columnDefinition = "serial", nullable = false)
  private Long id;

  @Length(max = 50)
  @Column(name = "name", length = 50)
  private String name;

  @OneToMany(fetch = FetchType.LAZY, targetEntity = TerritoryDataImpl.class)
  @JoinTable(name = "TERRITORY_WITH_SUBTERRITORIES",
      joinColumns = @JoinColumn(name = "id_parent_structure"), inverseJoinColumns = @JoinColumn(
          name = "ID_SUBTERRITORY"))
  private List<Territory> childrenStructures = new ArrayList<Territory>();

}

Upvotes: 2

Views: 799

Answers (1)

User1230321
User1230321

Reputation: 1475

This worked:

    @Entity
    @Table(name = "territory")
    public class TerritoryDataImpl {

      @Id
      @GeneratedValue
      @Column(name = "id", columnDefinition = "serial", nullable = false)
      private Long id;

      @Length(max = 50)
      @Column(name = "name", length = 50)
      private String name;

      @OneToOne(fetch = FetchType.EAGER, targetEntity = TerritoryDataImpl.class)
      @Column(name="ID_PARENT_TERRITORY")
      private TerritoryDataImpl parentTerritorialStructure;

      @OneToMany(mappedBy = "territoryStructure", targetEntity = TerritoryDataImpl.class,
          orphanRemoval = true, cascade = {CascadeType.REMOVE, CascadeType.MERGE})
      private List<Territory> childrenStructures = new ArrayList<Territory>();

      @ManyToOne(fetch = FetchType.EAGER, targetEntity = TerritoryDataImpl.class)
      @JoinTable(name = "TERRITORY_WITH_SUBTERRITORIES",
          joinColumns = @JoinColumn(name = "id_parent_structure"), inverseJoinColumns = @JoinColumn(
              name = "ID_SUBTERRITORY"))
      private TerritoryDataImpl territoryStructure;

    }

After territory collects parentStructure from UI, I've following code to save:

object.setTerritoryStructure(object.getParentTerritorialStructure());
entityManager.merge(territory);

Upvotes: 1

Related Questions