java - 在 Hibernate 的@Formula 中使用 NATURAL JOIN

标签 java mysql hibernate join formula

我在使用 @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 中,存在三种映射模型:UserPointsLogPointsRule

现在,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/

相关文章:

java - 在 DTO 中将同一变量用于两个目的是不好的做法吗

java - 如何获取二维数组的一部分?

php - 获取数据数组时出现 Codeigniter 错误

mysql - Doctrine - 具有自定义主键的ManyToMany

java - Hibernate 和 Spring Roo : org. hibernate.PersistentObjectException:传递给持久化的分离实体

mysql - 我应该改变这个数据库设计中的任何内容吗?

java - org.hibernate.exception.SQLGrammarException 不正确的 postgresql sql 查询

java - 无法执行 JDBC 批量更新

java - 正在创建多少个线程?

mysql - 如何查看远程访问 MYSQL 数据库的 IP?