我在使用NATURAL JOIN
的Hibernate中使用@Formula
时遇到问题。
我有三张桌子:
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
。
现在,@Formal
模型中有一个User
字段:
@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无法识别NATURAL JOIN
中的@Formula
。
有没有其他方法来实现这个功能?
@Formula(value = "(SELECT COUNT(*) FROM tz_points_logs pl WHERE pl.points_to_uid=uid)")
非常感谢。
答案 0 :(得分:1)
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