7

オプションのセットを、エンティティではEnumSetとして、データベースでは1対多の関係として表現したいと思います。これはどのように適切に行われますか?古い(注釈前の)回答または2つのテーブルを使用しない回答しか見つけることができません。

次のテーブルを定義しました。

CREATE TABLE Users (
    id                      SERIAL PRIMARY KEY,
    name                    VARCHAR(255) NOT NULL UNIQUE
);

CREATE TABLE User_Options (
    user_id                 INT,
    user_option             VARCHAR(255),
    PRIMARY KEY (user_id, user_option),
    FOREIGN KEY (user_id) REFERENCES Users(id)
                ON DELETE CASCADE
                ON UPDATE CASCADE
);

このエンティティクラス:

@Entity(name = "Users")
public final class User {

    @Id
    @GeneratedValue
    private int id;

    @Column(nullable = false, unique = true)
    private String name;

    private final Set<UserOption> options;

    {
        this.options = EnumSet.noneOf(UserOption.class);
    }

    /* plain getter for id included */

    /* plain getter and setter for name included */

    @ElementCollection(fetch = FetchType.EAGER)
    @Enumerated(EnumType.STRING)
    @CollectionTable(name = "User_Options"
            , joinColumns = @JoinColumn(name = "user_id"))
    @Column(name = "user_option", nullable = false)
    public Set<UserOption> getOptions() {
        return this.options;
    }

}

そしてもちろん列挙型:

public enum UserOption {

    OPTION_A,
    OPTION_B,
    OPTION_C;

}

Tomcatを起動すると、次の例外が発生します。

org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: Users, for columns: [org.hibernate.mapping.Column(options)]

この例外は、相互に発生する一連の例外のルートです。javax.persistence.PersistenceException(EntityManagerFactoryを構築できません)が発生し、依存性注入の例外が発生します。

私は、JPA / Hibernateに精通していないため、自分が間違っていることを理解できていないことを認めます。誰かが私を助けることができますか?

4

1 に答える 1

7

答えは思ったより簡単であることがわかりました。インスタンス変数とゲッターにJPAアノテーションを混在させることはできません。注釈自体は問題ありません。エンティティクラスを次のように変更しましたが、すべて正常に機能しています。

@Entity(name = "Users")
public final class User {

    @Id
    @GeneratedValue
    private int id;

    @Column(nullable = false, unique = true)
    private String name;

    @ElementCollection(fetch = FetchType.EAGER)
    @Enumerated(EnumType.STRING)
    @CollectionTable(name = "User_Options"
            , joinColumns = @JoinColumn(name = "user_id"))
    @Column(name = "user_option", nullable = false)
    private final Set<UserOption> options;

    {
        this.options = EnumSet.noneOf(UserOption.class);
    }

    /* plain getter for id included */

    /* plain getter and setter for name included */

    public Set<UserOption> getOptions() {
        return this.options;
    }

}
于 2013-02-12T11:46:28.927 に答える