4

私の英語で申し訳ありませんが、それは私の母国語ではなく、すでに2時なので、今は難しく考えることはできません. Java と PostgreSQL で hibernate を使用しているときに次の問題が発生しました。次のようなエンティティ Human と User があります (注釈マッピングあり):

    @Inheritance(strategy = InheritanceType.JOINED)
    public class Human implements Serializable{
        private static final long serialVersionUID = 1L;
        public static enum Gender{
            Male,
            Female}
        @Id
        @GeneratedValue
        private Integer id;
        @Enumerated(EnumType.STRING)
        private Gender gender;
        @Column
        @Temporal(TemporalType.DATE)
        private Date dateOfBirth;
        private String firstName;
        private String middleName;
        private String lastName;
        // getters,setters
    }

    @Entity
    @PrimaryKeyJoinColumn
    public class User extends Human{
        private static final long serialVersionUID= 1L;
        @Column
        @Temporal(TemporalType.DATE)
        private Date registrationDate;
        private Boolean activationStatus;
        private String activationCode;
        private String login;
        private String password;
        private String sessionCode;
        private String email;
        private String country;
        private String city;
        private String avatarURL;
        private String description;
        // getters,setters
    }

データベース構造は次のとおりです。

human
(
  dateofbirth date NOT NULL,
  firstname text NOT NULL,
  middlename text NOT NULL,
  lastname text NOT NULL,
  id serial NOT NULL,
  gender text,
  CONSTRAINT "Human_id" PRIMARY KEY (id )
)
"user"
(
  login text NOT NULL,
  password text NOT NULL,
  activationcode text NOT NULL,
  activationstatus status NOT NULL,
  avatarurl text NOT NULL,
  city text NOT NULL,
  country text NOT NULL,
  description text NOT NULL,
  registrationdate date NOT NULL,
  email text NOT NULL,
  id integer,
  CONSTRAINT uid PRIMARY KEY (id )
)

プロジェクト (単純な単体テスト) を実行しようとすると、次のエラーが発生します。

    org.postgresql.util.PSQLException: ERROR: column human0_1_.id does not exist
      Позиция: 778
        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2103)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1836)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:512)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:273)
        at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
        at org.hibernate.loader.Loader.getResultSet(Loader.java:1787)
        at org.hibernate.loader.Loader.doQuery(Loader.java:674)
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
        at org.hibernate.loader.Loader.loadEntity(Loader.java:1860)
        at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:48)
        at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:42)
        at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3044)
        at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:395)
        at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:375)
        at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:139)
        at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:195)
        at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:103)
        at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
        at org.hibernate.impl.SessionImpl.get(SessionImpl.java:815)
        at org.hibernate.impl.SessionImpl.get(SessionImpl.java:808)
        at org.tempos.server.modules.users.HumanTest.testGetId(HumanTest.java:31)
...

(invokin JUnit メソッドに応答している間、ログの末尾を切り取ります)。

生成されたクエリ (失敗):

select human0_.id as id3_0_, human0_.dateOfBirth as dateOfBi2_3_0_, human0_.firstName as firstName3_0_, human0_.gender as gender3_0_, human0_.lastName as lastName3_0_, human0_.middleName as middleName3_0_, human0_1_.activationCode as activati1_4_0_, human0_1_.activationStatus as activati2_4_0_, human0_1_.avatarURL as avatarURL4_0_, human0_1_.city as city4_0_, human0_1_.country as country4_0_, human0_1_.description as descript6_4_0_, human0_1_.email as email4_0_, human0_1_.login as login4_0_, human0_1_.password as password4_0_, human0_1_.registrationDate as registr10_4_0_, human0_1_.sessionCode as session11_4_0_, case when human0_1_.id is not null then 1 when human0_.id is not null then 0 end as clazz_0_ from Human human0_ left outer join User human0_1_ on human0_.id=human0_1_.id where human0_.id=?

ご覧のとおり、human1_1_.id (元は User.id) で列を結合しようとしていますが、クエリの SELECT 部分で指定および取得されていません。

私が試したこと:

  1. クラス ユーザーで @Column プライベート整数 ID を作成しています (クラスのプライマリ列をオーバーライドするための注釈パーサー例外を取得しました);
  2. クラス User に @Column プライベート Integer hid を作成し、それを PrimaryKeyJoinColumn として設定しました (ただし、@JoinColumn(insertable=false,updatable=false) としてマップしても (insert="false" update="false" でマップする必要があります) ,referencedColumnName="id"));
  3. 列「hid」を作成し、クラス全体ではなく、列自体への注釈でそれを PrimaryKeyJoinColumn として指定しました (元の列「human0_1_.id が見つかりません」と同じエラーが発生しました)。

どなたか、アイデアをください!

4

2 に答える 2

3

問題は解決されました。これは主に myhaylo のおかげです。
この問題の元の理由は、SQE PMD プラグインによって常にマークされていました。「ユーザー」は SQL-99 構文のキーワードです。このため (のように見えます)、テーブル名を引用符で囲む必要がありました。PgAdmin クエリ ブラウザでは引用されていましたが、Hibernate で生成されたクエリには含まれていませんでした。実際、その場合、user.id を指しているはずの human0_1_.id がどこも指していませんでした。
クラス名とテーブル名を他の名前 (AndhorUser など) に変更した後、元のデータベース構造が問題になり、クラス定義がうまく機能するようになりました。

于 2012-10-31T10:56:54.160 に答える
2

クラスは次のようになります。
人間

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Human implements Serializable {

    private static final long serialVersionUID = 1L;

    public static enum Gender {
        Male, Female
    }

    @Id
    @GeneratedValue
    private Long id;

    @Enumerated(EnumType.STRING)
    private Gender gender;
    private String firstName;
    private String lastName;

    public Long getId() {
        return id;
    }

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

    public Gender getGender() {
        return gender;
    }

    public void setGender(Gender gender) {
        this.gender = gender;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
   .....
}

ユーザー

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@PrimaryKeyJoinColumn
public class User extends Human {

    private static final long serialVersionUID = 1L;

    @Column
    @Temporal(TemporalType.DATE)
    private Date registrationDate;

    public Date getRegistrationDate() {
        return registrationDate;
    }

    public void setRegistrationDate(Date registrationDate) {
        this.registrationDate = registrationDate;
    }
    ....
}
  • 人間のクラスには@Entityアノテーションを付ける必要があります
  • モデルエンティティクラスは、Serializableインターフェイスを実装する必要があります

見る

  1. 継承タイプ(Hibernateあり)
  2. 継承タイプJOINED
于 2012-10-30T00:15:29.370 に答える