我在使用 @Formula
的 Hibernate 中使用 NATURAL JOIN
时遇到问题。
我有三个表:
CREATE TABLE IF NOT EXISTS `tz_points_logs` (
`points_log_id` bigint(20) NOT NULL,
`points_to_uid` bigint(20) NOT NULL,
`points_get_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`points_rule_id` int(4) NOT NULL,
`points_meta` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `tz_points_rules` (
`points_rule_id` int(4) NOT NULL,
`points_rule_credits` int(4) NOT NULL,
`points_rule_title` varchar(32) NOT NULL,
`points_rule_description` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `tz_users` (
`uid` bigint(20) NOT NULL,
`username` varchar(16) NOT NULL,
`password` varchar(32) NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
在 Hibernate 中,存在三种映射模型:User
、PointsLog
和 PointsRule
。
现在,User
模型中有一个@Formal
字段:
@Entity
@Table(name = "tz_users")
public class User implements Serializable {
// Getters and Setters
@Id
@GeneratedValue
@Column(name = "uid")
private long uid;
@Column(name = "username")
private String username;
@Column(name = "password")
private String password;
@OneToMany(targetEntity = PointsLog.class,
fetch = FetchType.LAZY, mappedBy = "user")
private List<PointsLog> pointsLogs = new ArrayList<PointsLog>();
@Formula(value = "(SELECT COUNT(*) FROM tz_points_logs pl NATURAL JOIN tz_points_rules WHERE pl.points_to_uid=uid)")
private long credit;
}
获取用户的信用时出现错误:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use
near 'user0_.NATURAL JOIN tz_points_rules WHERE pl.points_to_uid=user0_.uid) as formul' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:377)
at com.mysql.jdbc.Util.getInstance(Util.java:360)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:978)
...
at java.lang.Thread.run(Thread.java:745)
Hibernate 似乎无法识别@Formula
中的NATURAL JOIN
。
有没有其他方法可以实现这个功能?
顺便说一句,下面的语句工作正常。
@Formula(value = "(SELECT COUNT(*) FROM tz_points_logs pl WHERE pl.points_to_uid=uid)")
非常感谢。
最佳答案
在 this answer 中讨论了类似的问题.这里的重点是 - Hibernate 将 NATURAL
关键字视为属性/列名。解决方法应该是 - 在方言中将 NATURAL 注册为 keyword
。
例如:
// extend the correct dialect ... in this case MySql
// but simply extend the currently used dialect
public class CustomMySQLDialect extends MySQL5InnoDBDialect
{
public CustomMySQLDialect()
{
super();
registerKeyword("NATURAL");
}
}
接下来将 Hibernate 配置为使用此 CustomMySQLDialect
,并且应生成 FORMULA:
// instead of this
// user0_.NATURAL JOIN
// we should get this
NATURAL JOIN
关于java - 在 Hibernate 的@Formula 中使用 NATURAL JOIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28393424/