ゼリー:
私は、次のエンティティを持っています:
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "simple_entity")
public class SimpleEntity {
@Id
private Long id;
@Column(name = "text")
private String text;
}
私はいくつか取得したい追加の列を持つエンティティをデータベースから。これを行うには、私はシンプルなペアクラスを作成しました。
@Getter
@Setter
@AllArgsConstructor
public class Pair<First, Second> {
private First first;
private Second second;
}
それから私は、期待される結果を作成しJPQLでクエリを作成しました。
@Repository
public interface SimpleEntityRepository extends JpaRepository<SimpleEntity, Long> {
@Query("SELECT new com.example.demo.Pair(m, false) FROM SimpleEntity m")
List<Pair<SimpleEntity, Boolean>> getRecords();
}
クエリは、正しい結果を返しますが、追加のクエリに問題があります。
そのため、私はいくつかの質問を持っています:
- なぜ、JPAはこのように動作しますか?
- JPQL内の1つのクエリで、このデータを取得する方法はありますか?
- どのように私は(私が返すオブジェクトの溶液を見てきました[]が、それは素敵に見えない)いくつかの追加のデータと一緒にエンティティを取得する必要がありますか?
Lesiak:
ない完全な答えが、私はそれが議論にいくつかの情報が追加されますと信じて:
変圧器の結果
あなたは休止状態としてあなたの質問をマークとして、あなたは、Hibernate結果変圧器を使用することができます(5.2では非推奨としますが、6.0はアルファのままです):
List<Pair<SimpleEntity, Boolean>> resultList = entityManager.createQuery(
"select m as first, false as second from SimpleEntity m")
.unwrap(org.hibernate.query.Query.class)
.setResultTransformer(Transformers.aliasToBean(Pair.class))
.getResultList();
これは想定していPair
引数なしのコンストラクタを持っており、生成します。
select
simpleenti0_.id as col_0_0_,
0 as col_1_0_,
simpleenti0_.id as id1_18_,
simpleenti0_.text as text2_18_
from
simple_entity simpleenti0_
適切なDTO
フィールドのリストを経由して構築することができ、クラス全体ではなく、エンティティを使用してください。あなたが選択したフィールドのリストを指定すると、クエリがうまく動作します、全体ではなく実体
public class SimpleEntityDTO {
private Long id;
private String text;
private Boolean second;
public SimpleEntityDTO() {
}
public SimpleEntityDTO(Long id, String text, Boolean second) {
this.id = id;
this.text = text;
this.second = second;
}
// getters and setters
}
そして、あなたのクエリを変更します。
@Query("SELECT new com.example.demo.SimpleEntityDTO(m.id, m.text, false) FROM SimpleEntity m")
List<SimpleEntityDTO> getRecordsExtended();
これが生成します。
select
simpleenti0_.id as col_0_0_,
simpleenti0_.text as col_1_0_,
0 as col_2_0_
from
simple_entity simpleenti0_
総説
私は予測のエンティティ上のDTOを使用しての理由の一つは、彼らが管理されていないということであると信じています。エンティティは、DTOの一部であり、あなたのケースでは、エンティティが管理されます。
@Transactional
public void changeValueInFirstRecord() {
List<Pair<SimpleEntity, Boolean>> all = simpleEntityRepository.getRecords();
SimpleEntity firstEntity = all.get(0).getFirst();
boolean managed = entityManager.contains(firstEntity);
System.out.println("managed: " + managed); // true
firstEntity.setText("new value"); // firstEntity is updated
}
同じことが、結果変圧器の場合に当てはまります。
@Transactional
public void changeValueInFirstEntityViaTransformer() {
List<Pair<SimpleEntity, Boolean>> all = entityManager.createQuery(
"select m as first, false as second from SimpleEntity m")
.unwrap(org.hibernate.query.Query.class)
.setResultTransformer(Transformers.aliasToBean(Pair.class))
.getResultList();
SimpleEntity firstEntity = all.get(0).getFirst();
boolean managed = entityManager.contains(firstEntity);
System.out.println("managed: " + managed); // true
firstEntity.setText("new_value"); // firstEntity is updated
}