web-dev-qa-db-ja.com

MappedSuperclass-サブクラスのSequenceGeneratorを変更します

HibernateでJPA2を使用していて、エンティティに共通の基本クラスを導入しようとしています。これまでのところ、次のようになります。

@MappedSuperclass
public abstract class BaseEntity {

    @Id
    private Long id;

    @Override
    public int hashCode() {
        // ...
    }

    @Override
    public boolean equals(Object obj) {
        // ...
    }

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

ただし、すべてのテーブルには、シーケンスジェネレーターとして使用したいシーケンス$entityname_seqがあります。サブクラスからそれを設定するにはどうすればよいですか? @GeneratedValueをオーバーライドし、@ SequenceGeneratorを使用して新しいSequenceGeneratorを作成する必要があると思います。

27
atamanroman

はい、可能です。デフォルトのジェネレーター名は、@SequenceGeneratorアノテーションでオーバーライドできます。

  • 基本クラス
    @MappedSuperclass
    public abstract class PersistentEntity implements Serializable
    {
        private static final long serialVersionUID = 1L;

        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "default_gen")
        protected Long id = 0L;

        public Long getId()
        {
            return id;
        }

        public void setId(Long id)
        { 
            this.id = id;
        }
    }
  • シーケンス(SQL)

    create sequence role_seq;
  • 派生クラス

    @Entity
    @Table(name = "role")
    @SequenceGenerator(name = "default_gen", sequenceName = "role_seq", allocationSize = 1)
    public class Role extends PersistentEntity implements Serializable
    {
        private static final long serialVersionUID = 1L;

        @NotNull
        @Size(max = 32)
        private String name;

        public String getName()
        {
             return name;
        }

        public void setName(String name)
        {
             this.name = name;
        }   
    }
  • このアプローチはHibernate4.1.xでは正常に機能しましたが、EclipseLink2.xでは機能しませんでした。

編集

  • コメントによると、EclipseLink2.6.1-RC1で動作しているようです。
30
rbento

JPAでは、アノテーションでは実行できません。注釈自体をオーバーライドすることはできません。エンティティは、すべてのマッピング情報を MappedSuperClass から継承します。マップされたsuperClassから継承されたマッピングを再定義するために使用できるアノテーションは2つだけです。

  1. AttributeOverride 列のマッピングをオーバーライドし、
  2. AssociationOverride 結合列/テーブルをオーバーライドします。

どちらもGeneratedValueには役立ちません。

12
Mikko Maunu

EclipseLinkでは、Customizerを使用できます。 DescriptorCustomizerインターフェースは、jpa記述子(別名永続エンティティ)に関するすべての情報をカスタマイズする方法を定義します。

public class SequenceCustomizer implements DescriptorCustomizer {

    @Override
    public void customize(ClassDescriptor descriptor) throws Exception {
        descriptor.setSequenceNumberName(descriptor.getTableName());
    }
}

そしてあなたのマップされたスーパークラスで:

@MappedSuperclass
@Customizer(SequenceCustomizer.class)
public abstract class AbstractEntity implements Serializable {
    ...
}