list only has one element

gqmartins :

I'm using hibernate to read data from a database. I have 3 entities, sensor, zone and a N to N relationship between those two entities, that is the entity SensorZone.

For each entity I created a class, which are the examples that follow, they don't include a constructor, getters and setters:

@Entity
@Table(name = "Sensor")
public class Sensor {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "name")
    private String name;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "zone")
    private List<SensorZone> zones = new ArrayList<>();
}

@Entity
@Table(name = "Zone")
public class Zone {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "name")
    private String name;

    @Column(name = "max_count")
    private int maxCount;

    @Column(name = "current_count")
    private int currentCount;

    @Column(name = "created")
    private Timestamp created;

    @Column(name = "modified")
    private Timestamp modified;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "sensor")
    private List<SensorZone> sensors = new ArrayList<>();
}

@Entity
@Table(name = "Sensor_Zone")
public class SensorZone {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "zone_id")
    private Zone zone;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "sensor_id")
    private Sensor sensor;

    @Column(name = "enter_exit")
    private boolean enterExit;
}

I'm using PostgreSQL as a database engine, and the tables are as follow:

CREATE TABLE Sensor (
    id SERIAL,
    name TEXT NOT NULL UNIQUE,

    CONSTRAINT PK_Sensor PRIMARY KEY (id)
);

CREATE TABLE Zone (
    id SERIAL,
    name TEXT NOT NULL UNIQUE,
    max_count INT NOT NULL,
    current_count INT NOT NULL,
    created TIMESTAMP NOT NULL,
    modified TIMESTAMP NOT NULL,

    CONSTRAINT PK_Zone PRIMARY KEY (id)
);

CREATE TABLE Sensor_Zone (
    id SERIAL,
    zone_id INT NOT NULL,
    sensor_id INT NOT NULL,
    enter_exit BOOLEAN NOT NULL,

    CONSTRAINT PK_Zone_Sensor PRIMARY KEY (id, sensor_id, zone_id),
    CONSTRAINT FK_Zone_Sensor_Zone FOREIGN KEY (zone_id) REFERENCES Zone (id),
    CONSTRAINT FK_Zone_Sensor_Sensor FOREIGN KEY (sensor_id) REFERENCES Sensor (id)
);

And here's the values on the table Sensor_Zone:

Sensor_Zone values

The problem is that the field zones from Sensor only has one element in the list, even there are multiple elements in the database.

I've tried to put FecthType.EAGER, but it didn't change anything.

diginoise :

Not the exact solution (a.k.a. Could your model be re-modeled?)

I know it's easier said than done, but if you could avoid managing extra column(s) on the joining table, you could resolve it using standard example of many-to-many with joining table.

Perhaps there is a way of thinking about your extra column so that it could become owned by either Zone or Sensor entities? Maybe it's complementary as in on one side of many-to-many if it is set to TRUE it means one thing, but when it's missing it is equivalent to being FALSE.

@Entity
@Table(name = "Sensor")
public class Sensor {
  // ...
  @OneToMany
  @JoinTable(
    name = "Sensor_Zone", 
    joinColumns = { @JoinColumn(name = "sensor_id") }, 
    inverseJoinColumns = { @JoinColumn(name = "zone_id") }
  )
  private List<Zone> zones = new ArrayList<>();
}

@Entity
@Table(name = "Zone")
public class Zone {
  // ...
  @OneToMany
  @JoinTable(
    name = "Sensor_Zone", 
    joinColumns = { @JoinColumn(name = "zone_id") }, 
    inverseJoinColumns = { @JoinColumn(name = "sensor_id") }
  )
  private List<Sensor> sensors = new ArrayList<>();
}

And then your joining table does not need to be an entity simplifying things.


The Solution (Here be dragons)

Escape hatch: for solution please check Mykong's blog

You have to look into using @AssociationOverrides on the entity created from joining table. Please also note a separate class annotated with @Embeddable created to deal with the composite key in the joining table.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=126897&siteId=1