JPA Отношения загружаются только частично - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть две сущности, связанные N с N через таблицу отображения, которая сама является сущностью следующим образом

Rule 1<-->N Mapping N<-->1 Preference

Обе они реализуют связь с HashSet <>

Rule.java

 /**
  * List of {@link RulePreferenceMapping} belonging to this {@link Rule}
  */
 @OneToMany(
        mappedBy = "rule",
        cascade = CascadeType.ALL,
        fetch = FetchType.EAGER
 )
 private Set<RulePreferenceMapping> preferenceMappingList = new HashSet<>();

 @Override
public boolean equals(Object o)
{
    if (this == o)
    {
        return true;
    }

    if (o == null || getClass() != o.getClass())
    {
        return false;
    }

    return new EqualsBuilder()
                   .appendSuper(super.equals(o))
                   .isEquals();
}

@Override
public int hashCode()
{
    return new HashCodeBuilder(17, 37)
                   .appendSuper(super.hashCode())
                   .toHashCode();
}

RulePreference.java

  /**
  * List of {@link RulePreferenceMapping} pointing to this element
  */
 @OneToMany(
        mappedBy = "rulePreference",
        cascade = CascadeType.ALL,
        fetch = FetchType.EAGER
 )
 private Set<RulePreferenceMapping> ruleMappingList = new HashSet<>();

 @Override
public boolean equals(Object o)
{
    if (this == o)
    {
        return true;
    }

    if (o == null || getClass() != o.getClass())
    {
        return false;
    }

    RulePreference that = (RulePreference) o;

    return new EqualsBuilder()
                   .append(name, that.name)
                   .isEquals();
}

@Override
public int hashCode()
{
    return new HashCodeBuilder(17, 37)
                   .append(name)
                   .toHashCode();
}

RulePreferenceMapping.java

/**
 * {@link Rule} this element belongs to
 */
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "rule_id")
private Rule rule;

/**
 * {@link RulePreference} this mapping points to
 */
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "rule_preference_id")
private RulePreference rulePreference;

@Override
public boolean equals(Object o)
{
    if (this == o)
    {
        return true;
    }

    if (o == null || getClass() != o.getClass())
    {
        return false;
    }

    RulePreferenceMapping that = (RulePreferenceMapping) o;

    return new EqualsBuilder()
                   .append(rule, that.rule)
                   .append(rulePreference, that.rulePreference)
                   .isEquals();
}

@Override
public int hashCode()
{
    return new HashCodeBuilder(17, 37)
                   .append(rule)
                   .append(rulePreference)
                   .toHashCode();
}

Rule.java расширяет AbstractEntity, которое является @ MappedSuperclass и содержит только одно свойство

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Integer id;

@Override
public boolean equals(Object o)
{
    if (this == o)
    {
        return true;
    }

    if (o == null || getClass() != o.getClass())
    {
        return false;
    }

    AbstractEntity that = (AbstractEntity) o;

    return new EqualsBuilder()
                   .append(id, that.id)
                   .isEquals();
}

@Override
public int hashCode()
{
    return new HashCodeBuilder(17, 37)
                   .append(id)
                   .toHashCode();
}

Правило имеет другое отношение к RuleLevel.java (безтаблица соответствия, просто нормальное отношение 1 к N)

/**
 * {@link RuleLevel} this {@link Rule} belongs to
 */
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "rule_level_id")
private RuleLevel ruleLevel;

У меня есть встроенный HSQLDB для тестирования


- уровень правила

CREATE TABLE IF NOT EXISTS rule_level (
  id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL,
  name VARCHAR(255) NOT NULL,
  updated TIMESTAMP NOT NULL,
  PRIMARY KEY (id),
);

INSERT INTO rule_level (id, name, updated)
VALUES
(1, 'Country wide', current_timestamp),
(2, 'Department wide', current_timestamp),
(3, 'City wide', current_timestamp);

- правило

CREATE TABLE IF NOT EXISTS rule (
  id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL,
  name VARCHAR(255) NOT NULL,
  information VARCHAR(512) NULL,
  rule_level_id INT NULL,
  updated TIMESTAMP NOT NULL,
  PRIMARY KEY (id),
  FOREIGN KEY (rule_level_id) REFERENCES rule_level(id),
);

INSERT INTO rule (id, name, information, rule_level_id, updated)
VALUES
(1, 'Rule 1', 'Information Rule 1', 1, current_timestamp),
(2, 'Rule 2', null, 1, current_timestamp),
(3, 'Rule 3', null, null, current_timestamp),
(4, 'Rule 4', 'Information Rule 4', null, current_timestamp);

- предпочтения правила

CREATE TABLE IF NOT EXISTS rule_preference (
  id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL,
  name VARCHAR(255) NOT NULL,
  updated TIMESTAMP NOT NULL,
  PRIMARY KEY (id)
);

CREATE TABLE IF NOT EXISTS rule_preference_mapping (
  id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL,
  rule_id INT NOT NULL,
  rule_preference_id INT NOT NULL,
  updated TIMESTAMP NOT NULL,
  PRIMARY KEY (id),
  FOREIGN KEY (rule_id) REFERENCES rule(id),
  FOREIGN KEY (rule_preference_id) REFERENCES rule_preference(id),

INSERT INTO rule_preference (id, name, updated)
VALUES
(1, 'Preference 1', current_timestamp),
(2, 'Preference 2', current_timestamp),
(3, 'Preference 3', current_timestamp);

INSERT INTO rule_preference_mapping (id, rule_id, rule_preference_id, updated)
VALUES
(1, 1, 1, current_timestamp), -- set rule #1 to preference #1
(2, 2, 1, current_timestamp), -- set rule #2 to preference #1
(3, 3, 1, current_timestamp), -- set rule #3 to preference #1
(4, 1, 2, current_timestamp), -- set rule #1 to preference #2
(5, 2, 2, current_timestamp), -- set rule #2 to preference #2 **-- DON'T LOAD**
(6, 3, 2, current_timestamp); -- set rule #3 to preference #2 **-- DON'T LOAD**

Моя странная проблема заключается в том, что, пока мое правило имеет значение NULL, егоRuleLevel , из БД загружено только одно сопоставление с предпочтением.С этим набором данных мое Правило № 1 будет содержать 3 отображения предпочтений (идентификаторы 1, 2 и 3), но мое Правило № 2 будет содержать только сопоставление № 4.Два других просто не добавляются в набор.Конечно, я думал, что что-то происходит с моими equals () и hashCode (), но на самом деле это не так.

Пока я устанавливаю уровень для своего правила, он загружается, как и ожидалось.

Среда : Java8, Spring JPA с Hibernate

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...