0

ユーザーエンティティ

class User{
int id;
@OneToMany
Set<Role> roles;
}

:ユーザークラスには、私が書いていない他の多くの詳細があります。

DTO

class DTO{
int id;
Set<Role> roles;
DTO(int id, Set<Role> roles){
  this.id = id;
  this.roles= roles;
 }
}

クエリ

hibernateTemplate.find("select new DTO(u.id, r ) from "+User.class.getName()+ " u inner join u.roles as r");

問題: 有効なコンストラクターが見つかりませんでした。

以下のコンストラクターを変更すると、上記のクエリが機能します。

DTO(int id, Role role){
      this.id = id;
     }

問題: しかし、同じユーザーに対して複数の DTO レコードが与えられ、そのユーザーが持っているロールの数と同じになります。助けてください。

4

2 に答える 2

1

単一の DTO インスタンスを作成するには複数の行が必要なため、クエリ内で new 演算子を使用することはできません。代わりに、自分で DTO を作成する必要があります。このようなことをする必要があります:

Map<Long, DTO> dtosById = new LinkedHashMap<Long, DTO>();
List<Object[]> rows = hibernateTemplate.find("select u.id, r from User u inner join u.roles as r");
for (Object[] row : rows) {
    Long id = (Long) row[0];
    Role role = (Role) row[1];
    DTO dto = dtosById.get(id);
    if (dto == null) {
        dto = new DTO(id);
        dtosById.put(id, dto);
    }
    dto.addRole(role);
}
List<DTO> dtos = new ArrayList<DTO>(dtosById.values());
于 2012-07-23T14:52:22.273 に答える
0

物事を簡単にしたい場合は、まさにそのユース ケースのために作成したBlaze-Persistence Entity-Viewsを気に入るはずです。基本的に、JPA エンティティの DTO をインターフェイスとして定義し、それらをクエリに適用します。ネストされた DTO、コレクションなどのマッピングをサポートし、基本的に期待されるすべてのものに加えて、DTO に実際に必要なデータだけを取得するクエリを生成するため、クエリのパフォーマンスが向上します。

この例のエンティティ ビューは次のようになります。

@EntityView(User.class)
interface UserDto {
  @IdMapping Integer getId();
  List<RoleDto> getRoles();
}
@EntityView(Role.class)
interface RoleDto {
  @IdMapping Integer getId();
  String getName();
}

クエリは次のようになります

List<UserDto> dtos = entityViewManager.applySetting(
  EntityViewSetting.create(UserDto.class),
  criteriaBuilderFactory.create(em, User.class)
).getResultList();
于 2018-07-19T18:39:09.220 に答える