Отсутствующие строки с пустым значением в запросе на спящий режим

У меня есть две таблицы с внешними ключевыми ссылками:

Comm TABLE:

+----+------------+
| ID |    NAME    |
+----+------------+
|  1 | comm name1 |
|  2 | comm name2 |
|  3 | comm name3 |
+----+------------+

LOCATION TABLE: - COMM_ID FK to  Comm --> id

+---------+------+-----+
| COMM_ID | FORM | TO  |
+---------+------+-----+
|       1 | 720  | 721 |
|       1 | 725  |     |
|       1 |      | 766 |
|       1 |      |     |
|       2 | 766  | 225 |
|       3 | 766  | 222 |
+---------+------+-----+

Проблема заключается в том, что Hibernate возвращает мой объект comm с отсутствующим location в SET<location> Все строки, в которых нет FROM и TO (например, последняя строка с COMM_ID = 1 в таблице LOCATION), отсутствуют.

В противном случае (если только один из FROM или TO) строка возвращается... почему?

Comm объекты:

@ElementCollection
@CollectionTable(name="LOCATION",[email protected](name="COMM_ID"))
 public Set<LOCATION> getLocations(){
    return locations;
 }
 public void setLocations(Set<LOCATION> locations){
    this.locations=locations;
 }

location класс:

@Embeddable
class Location implements java.io.Serializable {

    private BigDecimal fromLocationId;
    private BigDecimal toLocationId;

    public Location() {
    }

    public Location(BigDecimal fromLocationId, BigDecimal toLocationId) {
        this.fromLocationId = fromLocationId;
        this.toLocationId = toLocationId;
    }

    @Column(name="FROM", nullable=true, precision=22, scale=0)
    public BigDecimal getFromLocationId() {
        return this.fromLocationId;
    }

    public void setFromLocationId(BigDecimal fromLocationId) {
        this.fromLocationId = fromLocationId;
    }

    @Column(name="TO", nullable=true, precision=22, scale=0)
    public BigDecimal getToLocationId() {
        return this.toLocationId;
    }

    public void setToLocationId(BigDecimal toLocationId) {
        this.toLocationId = toLocationId;
    }

    @Override
    public int hashCode() {
        return com.google.common.base.Objects.hashCode(fromLocationId, toLocationId);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        final LOCATION  other = (LOCATION) obj;
        return com.google.common.base.Objects.equal(this.fromLocationId, other.fromLocationId) && com.google.common.base.Objects.equal(this.toLocationId, other.toLocationId);
    }
}

Я использую Hibernate - 4.3.6

LOG:

org.hibernate.SQL - 
    select
        locations0_.COMM_ID as COMM_ID1_2_0_,
        locations0_.FROM as FROM2_8_0_,
        locations0_.TO as TO4_8_0_
    from
        LOCATION  locations0_ 
    where
        locations0_.COMM_ID=1

Я проверил его в своей БД и вернул правильный результат.

Ответ 1

Собственно, нет ничего плохого в выходе. Я думаю, вы просто путаетесь между embeddable и entity. потому что, насколько я знаю. Вы используете только класс embeddable только для того, чтобы сделать разработку объекта намного проще, если есть много объектов, которые используют одни и те же поля.

И из того, что я вижу, методы hashcode и equals обрабатывают все эти шесть записей как другую запись. Итак, я думаю, что вы хотите сделать класс Location чем-то вроде этого.

@Entity
class Location implements java.io.Serializable {

private Long commId;
private BigDecimal fromLocationId;
private BigDecimal toLocationId;

// all the setter getter here

@Override
public int hashCode() {
    return com.google.common.base.Objects.hashCode(commId);
}

@Override
public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null || getClass() != obj.getClass()) {
        return false;
    }
    final LOCATION  other = (LOCATION) obj;
    return com.google.common.base.Objects.equal(this.commId, other.commId);
}
}

или, конечно, вы можете заставить метод get вернуть List, а затем удалить строку, если строка отсутствует from или to значение.

Ответ 2

Вложенные данные объекта содержатся в нескольких столбцах в родительской таблице. Поскольку нет единственного значения поля, нет способа узнать, является ли родительская ссылка на вложенное значение null. Можно предположить, что если каждое значение поля вложенного значения равно null, то ссылка должна быть нулевой, но тогда нет возможности представить вложенный в нее все нулевые значения. JPA не допускает, чтобы вложения были пустыми, но некоторые поставщики JPA могут это поддержать.

Спящий режим: при загрузке объекта вложенные ссылки устанавливаются равными нулю, если все столбцы вложенного являются нулевыми.

для получения дополнительной информации нажмите здесь

поэтому, когда u сохраняет значения с возможностью сбрасывания встраиваемых значений, тогда hibernate позволяет сохранять, но во время выборки hibernate отбрасывать те строки, которые являются нулевыми.