3

Dozer を使用して、ドメイン エンティティを DTO オブジェクトに変換しようとしています。だから、PersistentList、PersistentBag、...を私のドメインエンティティからArrayListに変換したい...私のDTOオブジェクトでは、怠惰な問題を避けることができます。

これは、私のドメイン エンティティの 2 つの例です。

public class User {
      private Collection<Role> roles;
      ...
}

public class Role {
      private Collection<User> users;
      ...
}

クラスがDTO型であることを除いて、私のDTOオブジェクトは同じです。したがって、ドメインを DTO オブジェクトに変換するには、次の Dozer マッピングを使用します。

 <configuration>
  <custom-converters>
   <converter type=com.app.mapper.converter.BagConverter">
    <class-a>org.hibernate.collection.PersistentBag</class-a>
    <class-b>java.util.List</class-b>
   </converter>
  </custom-converters>
 </configuration>

 <mapping>
  <class-a>com.app.domain.User</class-a>
  <class-b>com.app.dto.UserDTO</class-b>
 </mapping>

 <mapping>
  <class-a>com.app.domain.Role</class-a>
  <class-b>com.app.dto.RoleDTO</class-b>
 </mapping>

BagConverter は Dozer カスタム コンバーターであり、それがそのコードです。

  public class BagConverter<T> extends DozerConverter<PersistentBag, List>{

 public BagConverter() {
  super(PersistentBag.class, List.class);
 }

 public PersistentBag convertFrom(List source, PersistentBag destination) {
  PersistentBag listDest = null;

  if (source != null) {

   if (destination == null) {
    listDest = new PersistentBag();
   } else {
    listDest = destination;
   }

   listDest.addAll(source);
  }

  return listDest;
 }

 public List convertTo(PersistentBag source, List destination) {
  List listDest = null;

  if (source != null) {

   if (destination == null) {
    listDest = new ArrayList<T>();
   } else {
    listDest = destination;
   }

   if (source.wasInitialized()) {
    listDest.addAll(source);
   }
  }

  return listDest;
 }}

したがって、ロールを持つ PersistentBag を含む User オブジェクトを取得します。そのオブジェクトに dozer マッパー マップを適用して、UserDTO オブジェクトを取得します。取得した結果は、Role の ArrayList を持つ UserDTO オブジェクトであり、RoleDTO の ArrayList はありません。

カスタム コンバーターを使用しても、dozer はリストの内容を変換してくれると思いました。それは正しい方法ではありませんか?いいえの場合、永続的なコレクションを従来の Java コレクションに置き換えて、ドメイン エンティティを dto オブジェクトに変換するにはどうすればよいですか?

ご協力いただきありがとうございます。

シルヴァン。

4

4 に答える 4

1

残念ながら、を登録するCustomConverterと、すべてのコンテンツ、プロパティ、要素などを含むオブジェクト(あなたの場合はコレクション)のマッピングに対して全責任を負います。

私が今見ているように (以前は見たことがありませんでした。何らかの新機能である必要があります)。Dozer docs の Custom Type ConvertersMapperAwareの章の最後で説明されているように、インターフェイスを使用する可能性があります。これはまさにあなたのニーズに合ったものだと思います。

于 2010-05-13T16:43:40.423 に答える
1

Dozer を使用して、ドメイン エンティティを DTO オブジェクトに変換しようとしています。だから、PersistentList、PersistentBag、...を私のドメインエンティティからArrayListに変換したい...私のDTOオブジェクトでは、怠惰な問題を避けることができます。

最後の文を取得しましたが、o.h.c.PersistentBagこのクラスList. 次のようなものを使用してください:

<mapping>
  <class-a>com.myapp.domain.User</class-a>
  <class-b>com.myapp.dto.UserDTO</class-b>
  <field>
    <a>roles</a>
    <b>roles</b>
    <a-hint>com.myapp.domain.Role</a-hint>
    <b-hint>com.myapp.dto.RoleDTO</b-hint>
  </field>
</mapping>

そして、エンティティをデタッチする前に変換を実行します(それが問題の鍵です)。

于 2010-05-13T21:34:59.430 に答える
0

Pascal が言うように、PersistentBags を直接使用する意味がわかりません。@Entity POJO でロールのリストをクラシックとして宣言するとjava.util.List、Hibernate は自動的にその内部表現を使用します。これが、シリアル化プロセスで POJO を使用できない理由でもあります。明確にするために:

@Entity
public class User {
  private java.util.List<Role> roles = new java.util.Arraylist<Role>(); //Hibernate doesn't really care about this new Arraylist stuff, it will use its org.hibernate.collection.PersistentList
  ... //other fields and methods
}

エンティティ POJO を DTO オブジェクトに変換する場合は、Pascal によって提案されたマッピング (別名) を使用するだけです。

<mapping>
  <class-a>com.myapp.domain.User</class-a>
  <class-b>com.myapp.dto.UserDTO</class-b>
  <field>
    <a>roles</a>
    <b>roles</b>
    <a-hint>com.myapp.domain.Role</a-hint>
    <b-hint>com.myapp.dto.RoleDTO</b-hint>
  </field>
</mapping>

遅延初期化例外を回避するために、トランザクションを閉じる前に変換を行います。

@Transactional
public UserDTO getUser(...) {
  User user = dao.getUser(...);
  UserDTO dto = //Place your Dozer conversion here
  return dto;
}

ちょっとしたメモとして、私は同じ理由で Dozer を使用していましたが、これは魅力的に機能していました。

于 2013-01-03T09:12:22.487 に答える
0

そのようなカスタムコンバーターを使用しない他のソリューションもテストしました:

<mapping>
    <class-a>com.myapp.domain.User</class-a>
    <class-b>com.myapp.dto.UserDTO</class-b>
    <field>
        <a>roles</a>
        <b>roles</b>
        <a-hint>com.myapp.domain.Role</a-hint>
        <b-hint>com.myapp.dto.RoleDTO</b-hint>
    </field>
</mapping>

別の問題があります。Dozer がロールを User から UserDTO の RoleDTO のロールに変換しようとすると、Hibernate から遅延初期化例外が発生します。これは、ユーザーのロールが EAGER モードであるためです。

だから、そのマッピングを行う方法がわかりません。私はこれらの問題を解決する方法を探し続けています

于 2010-05-14T09:33:43.423 に答える