Hibernate, объединяющий 2 ряда

Чтобы упростить мой Java-код, я хотел бы объединить две строки в одну, поскольку мне действительно нужны эти две строки для использования данных.

Допустим, это поля моей таблицы:

ID, FIELD1, FIELD2, DISCRIMINATOR, VALUE

Очевидно, ID является первичным ключом. FIELD1 и 2 позволяют нам идентифицировать "группу" из 2 строк, которые отличаются только DISCRIMINATOR и VALUE (дискриминатор указывает, что представляет значение)

И я хотел бы иметь один POJO на "группу" (где FIELD1 и 2 будут использоваться в качестве составного идентификатора), например:

FIELD1, FIELD2, VALUE1, VALUE2

Куда:

VALUE1 = VALUE для дискриминатора A

VALUE2 = VALUE для дискриминатора B

В SQL я бы запросил это так:

SELECT a.FIELD1, a.FIELD2, a.VALUE as VALUE1, b.VALUE as VALUE2
FROM TABLE a, TABLE b
WHERE a.FIELD1 = b.FIELD1 and a.FIELD2 = b.FIELD2
  AND a.DISCRIMINATOR = 'A'
  AND b.DISCRIMINATOR = 'B'

К сожалению, я не знаю, как сделать это в спящем режиме, и теперь я запутался со всеми возможностями.

Я предпочел бы иметь решение в виде отображенного XML, но все равно использовал бы решение для аннотаций, если нет выбора.

1 ответ

Если вы очень просто сопоставите таблицу с POJO (здесь используются аннотации, но вы можете использовать XML):

@Entity
@Table(name = "whatever")
public class Fields {

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

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

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

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

    @Column(name = "VALUE")
    private String value;
}

Вы можете определить отдельный POJO, который содержит поля и значения:

public class FieldValues {
    private String field1, field2, value1, value2;

    public FieldValues( String field1, String field2, String value1, String value2 ) {
        this.field1 = field1;
        this.field2 = field2;
        this.value1 = value1;
        this.value2 = value2;
    }
}

Затем вы можете использовать JPQL, чтобы написать именно тот запрос, который вы обрисовали в общих чертах, выполнить его в EntityManager и он все равно будет участвовать во всех транзакциях JPA и так далее.

String sql =   "SELECT a.field1, a.field2, a.value as value1, b.value as value2 "
             + "  FROM Fields a, Fields b "
             + " WHERE a.FIELD1 = b.FIELD1 and a.FIELD2 = b.FIELD2 "
             + "   AND a.DISCRIMINATOR = 'A' "
             + "   AND b.DISCRIMINATOR = 'B'";
List<Object[]> result = entityManager.createQuery(sql, Object[].class);

List<FieldValues> result = new ArrayList<FieldValues>();
for (Object[] fieldSet : result) {
    String field1 = (String) fieldSet[0];
    String field2 = (String) fieldSet[1];
    String value1 = (String) fieldSet[2];
    String value2 = (String) fieldSet[3];
    result.add(new FieldValues(field1, field2, value1, value2));
}

Я верю, что вы даже можете получить Hibernate, чтобы отобразить FieldValues для вас, но я не помню, как. Это может быть так же просто, как просто аннотировать (или XML-отображение) FieldValues класс с правильными именами столбцов, а затем вынуждает Hibernate возвращать List<FieldValues> вместо этого из запроса. Недостатком этого подхода является то, что вы не можете вносить изменения в FieldValue и сохранить его в базе данных.

Другой подход заключается в использовании простого старого SQL с EntityManager.createNativeQuery, Вы должны убедиться, что вы очистили менеджер сущностей, прежде чем делать это; в противном случае ожидающие изменения могут быть не записаны в базу данных и, следовательно, не будут видны по вашему запросу. Опять же, я верю, что вы можете получить Hibernate для сопоставления с FieldValues класс в этом случае для вас.

Другие вопросы по тегам