2017-07-11 2 views
0

私はテーブルとして、カスタムJavaオブジェクトを表すことにより、永続化APIとEbeanを使用して、MySQLデータベースにいくつかのテーブルを構築しました。今では、Ebean.find()の引数として渡して、格納されている項目を回復しようとしますが、いつでもオブジェクトを照会しますが、毎回javax.persistence.PersistenceExceptionがスローされます。プレイフレームワーク - Ebean - クラス「クラス名」に登録されませんScalarType


私は階層構造を説明しましょう:2つのサブクラスでは

@Entity 
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name = "MACHINE_TYPE") 
public class Machine extends Model 
{ 
    @Id 
    @Column(name = "id") 
    private Long _machineID; 

    @Column(name = "name", unique = true) 
    private String _name; 

    @Column(name = "info") 
    private String _info; 

    // rest of code 
} 

マシンクラスは

があります。

@Entity 
@Table(name = "machine") 
@DiscriminatorValue("Server") 
public class Server extends Machine 
{ 
    @Column(name = "ip") 
    private String _ip; 

    @Column(name = "port") 
    private Integer _port; 

    @Column(name = "user_name") 
    private String _userName; 

    @Column(name = "password") 
    private String _password; 

    @Column(name = "clock") 
    private Integer _clock; 

    @Column(name = "ram") 
    private Integer _ram; 

    // rest of code 
} 

そしてコンテナクラス:

@Entity 
@Table(name = "machine") 
@DiscriminatorValue("Container") 
public class Container extends Machine 
{ 
@Column(name = "dockerID", unique = true) 
    private String _dockerID; 

    @ManyToOne 
    @JoinColumn(name = "host", insertable = true, updatable = true) 
    private Server _host; 

    @Column(name = "currentSize") 
    private String _currentSize; 

    @Column(name = "additionalInfo") 
    private String _additionalInfo; 

    @Column(name = "last_login") 
    private String _lastLogin; 

    // rest of code 
} 

このコード、次のようにMySQLデータベースにおける機械テーブルを構築します。

を次のようにマシン を拡張サーバークラス
`machine` (
    `machine_type` varchar(31) NOT NULL, 
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) DEFAULT NULL, 
    `info` mediumtext, 
    `dockerID` varchar(255) DEFAULT NULL, 
    `host` bigint(20) DEFAULT NULL, 
    `currentSize` varchar(255) DEFAULT NULL, 
    `additionalInfo` text, 
    `last_login` varchar(255) DEFAULT NULL, 
    `ip` varchar(255) DEFAULT NULL, 
    `port` int(11) DEFAULT NULL, 
    `user_name` varchar(255) DEFAULT NULL, 
    `password` varchar(255) DEFAULT NULL, 
    `clock` int(11) DEFAULT NULL, 
    `ram` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `uq_machine_dockerID` (`dockerID`), 
    KEY `ix_machine__host_4` (`host`), 
    CONSTRAINT `fk_machine__host_4` FOREIGN KEY (`host`) REFERENCES `machine` (`id`) 
) 

これは正しいようです。

javax.persistence.PersistenceException: No ScalarType registered for class com.project.models.Server 
    at com.avaje.ebeaninternal.server.persist.Binder.bindObject(Binder.java:158) 
    rest of the StackTrace 

私は

List<Container> testcase = Ebean.find(Container.class) 
        .where() 
        .eq("host", server.getMachineId()) // pass the serverID 
        .findList(); 

でクエリを変更しようとしても:私はDBにエントリを追加し、

... 
Server server = Server.getServerByName(serverName); // this returns a Server object correctly 
List<Container> testCase = Ebean.find(Container.class) 
        .where() 
        .eq("host", server) 
        .findList(); // this throws the exception 

を実行しようとした場合でも、私が言ってPersistenceExceptionを得ました私は別の例外表すだ:

javax.persistence.PersistenceException: Query threw SQLException:Column 'host' in where clause is ambiguous 
Bind values:[1] 
Query was: 
select t0.machine_type c0, t0.id c1, t0.name c2, t0.info c3, t0.dockerID c4, t0.currentSize c5, 
t0.additionalInfo c6, t0.last_login c7, t1.machine_type c8, t0.host c9 from machine t0 
left outer join machine t1 on t1.id = t0.host and t1.machine_type = 'Server' 
where t0.machine_type = 'Container' and host = ? 

すべてのヘルプは、少なくともどのような方向に従うにとても

答えて

0

を理解されるであろうし、いくつかのテストの後、私はあなたがオブジェクトとデータベーステーブルにアクセスしたい場合は、あなたにいくつかのルールに従う必要があることが分かりました明らかに私はしませんでした。ドキュメントのどこにも、私はこれを見つけることができます。この解決策は、失敗と試行の結果です。


最初に、変数の名前は列の名前と同じでなければなりません。私はにContainer.classServer.classの変数を変更した場合:

@ManyToOne 
@JoinColumn(name = "host", insertable = true, updatable = true) 
private Server host; // notice the name is the same as the column name 

すべてが正常に動作し、私は次のようにクエリでServer.classオブジェクトを渡すことができますので、オブジェクトの実体をマッピングするために

Ebean.find(Container.class) 
     .where() 
     .eq("host", server) 
     .findList(); 

、列名が正確に同じでなければなりません変数名とその逆もあります。私の場合は主要な問題ではありません

@ManyToOne(targetEntity = Server.class) // explicitly specify the target class 
@JoinColumn(name = "host", insertable = true, updatable = true) 
private Server host; 

これが、理由:


第二に、そして私の知る限りでは、ドキュメントを読み込むように、我々は次のように@ManyToOne注釈にターゲットエンティティを指定することができますJavaはhostフィールドのクラスタイプを読み取り、ターゲットエンティティを自動的に渡します。しかしここで安全である方が良い。

関連する問題