5

パッケージを使用しjavax.persistenceて Java クラスをマップしています。

次のようなエンティティがあります。

public class UserEntity extends IdEntity {
}

という名前のマップされたスーパークラスを拡張しますIdEntity:

@MappedSuperclass
public class IdEntity extends VersionEntity {

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

    // Getters and setters below...    

}

スーパー クラスは、すべてのエンティティがバージョン プロパティを継承するように名前が付けられた別のマップされたIdEntityスーパー クラスを拡張します。VersionEntity

@MappedSuperclass
public abstract class VersionEntity {

    @Version
    private Integer version;

    // Getters and setters below...

}

なんで?

これで、すべてのエンティティに対して IdEntity クラスで一般的なクエリを作成できるようになり、次のようになります: (例)

CriteriaBuilder builder = JPA.em().getCriteriaBuilder();
CriteriaQuery<IdEntity> criteria = builder.createQuery(IdEntity.class);

今問題に。

私のエンティティのcreated_atには、 や のようなタイムスタンプを持つものがありdeleted_atます。しかし、すべてのエンティティではありません。

これらのプロパティをエンティティ クラスで次のように指定できます。

public class UserEntity extends IdEntity {

    @Basic(optional = false)
    @Column(name = "updated_at")
    @Temporal(TemporalType.TIMESTAMP)
    private Date updatedAt;
}

しかし、私は多くのエンティティを持っているので、タイムスタンプが必要なすべてのエンティティに多くの冗長なコードを配置する必要があります。関連するクラスに何らかの方法でこれらのフィールドを継承させる方法があればいいのにと思います。

IdEntity考えられる解決策の 1 つは、おそらく名前を付けた並列スーパークラスを作成し、IdAndTimeStampEntity代わりにタイムスタンプを持つ必要があるエンティティをこの新しいスーパークラスから継承させることですが、同僚の開発者にとっては公平ではありません。一般的なクエリを書く:

CriteriaBuilder builder = JPA.em().getCriteriaBuilder();
CriteriaQuery<???> criteria = builder.createQuery(???); // Hmm which entity should I choose IdEntity or IdAndTimeStampEntity ?? *Annoyed*

そして、一般的なエンティティクエリはそれほど一般的ではなくなります..

私の質問:allエンティティを継承idして versionフィールドを作成するにはどうすればよいですか?ただし、すべてのエンティティのサブ部分のみがタイムスタンプ フィールドを継承し、クエリを単一のタイプのエンティティに保持しますか?

更新 #1

Bolzano からの質問: 「エンティティのパス (テーブル情報を保持する) を指定するコードを追加できますか?」

UserEntityこれは、a である a を照会する実際の例ですIdEntity

CriteriaBuilder builder = JPA.em().getCriteriaBuilder();
CriteriaQuery<IdEntity> criteria = builder.createQuery(IdEntity.class);
Root<IdEntity> from = criteria.from(IdEntity.class);
criteria.select(from);

Path<Integer> idPath = from.get(UserEntity_.id); //generated meta model
criteria.where(builder.in(idPath).value(id));

TypedQuery<IdEntity> query = JPA.em().createQuery(criteria);
return query.getSingleResult();
4

3 に答える 3

2

関連するクラスに何らかの方法でこれらのフィールドを継承させる方法があればいいのにと思います。

バイトコード操作フレームワークを使用するか、委任サブクラスを作成することにより、カスタム アノテーション@Timedを作成し、アノテーション プロセッサを使用してタイムスタンプ フィールドとアノテーションを追加できます。または、たとえば Lombok を使用する場合は、Lombok アノテーションを作成します。

@Timedそうすれば、タイムスタンプ付きのエンティティがある場合に、チーム メンバーは注釈を使用することを覚えておくだけで済みます。そのようなアプローチが好きかどうかはあなた次第です。

于 2016-12-01T08:56:14.673 に答える