Play Framework - Ebean - class "class name" 没有注册 ScalarType
Play Framework - Ebean - No ScalarType registered for class "class name"
我在 MySQL 数据库中构建了一些 tables,使用持久性 API 和 Ebean,将自定义 Java 对象表示为 tables。现在,我尝试通过在 Ebean.find() 查询中作为参数传递我想要的对象来恢复存储的条目,但是每次都会抛出 javax.persistence.PersistenceException
。
让我解释一下层次结构:
有一台机器 class:
@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
}
有两个子class。 Server class 扩展 Machine 如下:
@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
}
还有一个容器 class:
@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数据库中建立一个机器table如下:
`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`)
)
这似乎是正确的。但是,如果我在数据库中添加一个条目并尝试执行
...
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: 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();
我得到另一个异常表示:
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 = ?
任何帮助,至少在遵循的方向上,我们将不胜感激
所以,经过一些测试,我发现如果你想访问包含对象的数据库表,你需要在你的对象映射中遵循一些规则,显然我没有。在文档中的任何地方我也找不到它。此解决方案是失败并尝试的结果。
首先,变量的名称必须与列的名称相同!如果我将 Container.class
和 Server.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
注释中指定目标实体,如下所示:
@ManyToOne(targetEntity = Server.class) // explicitly specify the target class
@JoinColumn(name = "host", insertable = true, updatable = true)
private Server host;
虽然这不是我的主要问题,因为 Java 读取 host
字段的 class 类型并自动传递目标实体。但最好在这里注意安全。
我在 MySQL 数据库中构建了一些 tables,使用持久性 API 和 Ebean,将自定义 Java 对象表示为 tables。现在,我尝试通过在 Ebean.find() 查询中作为参数传递我想要的对象来恢复存储的条目,但是每次都会抛出 javax.persistence.PersistenceException
。
让我解释一下层次结构:
有一台机器 class:
@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
}
有两个子class。 Server class 扩展 Machine 如下:
@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
}
还有一个容器 class:
@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数据库中建立一个机器table如下:
`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`)
)
这似乎是正确的。但是,如果我在数据库中添加一个条目并尝试执行
...
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: 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();
我得到另一个异常表示:
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 = ?
任何帮助,至少在遵循的方向上,我们将不胜感激
所以,经过一些测试,我发现如果你想访问包含对象的数据库表,你需要在你的对象映射中遵循一些规则,显然我没有。在文档中的任何地方我也找不到它。此解决方案是失败并尝试的结果。
首先,变量的名称必须与列的名称相同!如果我将 Container.class
和 Server.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
注释中指定目标实体,如下所示:
@ManyToOne(targetEntity = Server.class) // explicitly specify the target class
@JoinColumn(name = "host", insertable = true, updatable = true)
private Server host;
虽然这不是我的主要问题,因为 Java 读取 host
字段的 class 类型并自动传递目标实体。但最好在这里注意安全。