"Could not prepare statement"一对多
"Could not prepare statement" OneToMany
这是我想要实现的目标:
Write a web service that gives the details of a repository: id, name, user name and
list of commits.
需要以JSON
格式返回,例如:
{
"repository_id": "1",
"repository_name": "My repo",
"owner": "Noah",
"commits": [
"First commit",
"Second commit",
"Third commit"
]
}
您会发现数据库结构如下:
这是我的 CrudRepository
我正在尝试构建的查询:
public interface RepositoriesDB extends CrudRepository<Repository, String> {
@Query(value = "SELECT r.repositoryId, r.repositoryName, r.owner.userName, r.commits FROM Repository r WHERE r.repositoryId = :repoId")
List<Object[]> getRepo(@Param("repoId") long repoId);
}
我的 User
class :
@Entity
@NoArgsConstructor
@Data
public class User {
@NotNull
@Id
private String userLogin;
@NotBlank
@NotNull
private String userName;
@OneToMany(mappedBy = "owner", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JsonIgnore
private List<Repository> repositories;
}
我的 Repository
class :
@Entity
@NoArgsConstructor
@Data
public class Repository {
@NotNull
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long repositoryId;
@NotNull
@NotBlank
@Size(min = 3, max = 25)
private String repositoryName;
@OneToMany(mappedBy = "repository", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JsonIgnore
private List<Commit> commits;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "owner_login", nullable = false)
private User owner;
}
我的 Commit
class :
@Entity
@NoArgsConstructor
@Data
public class Commit {
@NotNull
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long commitId;
@NotBlank
@NotNull
private LocalDateTime date = LocalDateTime.now();
@NotNull
@NotBlank
@Size(min = 1, max = 255)
private String message;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "repository_id", nullable = false)
private Repository repository;
}
最后,这里是堆栈跟踪:
There was an unexpected error (type=Internal Server Error, status=500).
could not prepare statement; SQL [select repository0_.repository_id as col_0_0_, repository0_.repository_name as col_1_0_, user1_.user_name as col_2_0_, . as col_3_0_, commits2_.commit_id as commit_i1_0_, commits2_.date as date2_0_, commits2_.message as message3_0_, commits2_.repository_id as reposito4_0_ from repository repository0_ cross join user user1_ inner join commit commits2_ on repository0_.repository_id=commits2_.repository_id where repository0_.owner_login=user1_.user_login and repository0_.repository_id=?]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [select repository0_.repository_id as col_0_0_, repository0_.repository_name as col_1_0_, user1_.user_name as col_2_0_, . as col_3_0_, commits2_.commit_id as commit_i1_0_, commits2_.date as date2_0_, commits2_.message as message3_0_, commits2_.repository_id as reposito4_0_ from repository repository0_ cross join user user1_ inner join commit commits2_ on repository0_.repository_id=commits2_.repository_id where repository0_.owner_login=user1_.user_login and repository0_.repository_id=?]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:259)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551)
[...]
Caused by: org.hibernate.exception.SQLGrammarException: could not prepare statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:63)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
[...]
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "SELECT REPOSITORY0_.REPOSITORY_ID AS COL_0_0_, REPOSITORY0_.REPOSITORY_NAME AS COL_1_0_, USER1_.USER_NAME AS COL_2_0_, .[*] AS COL_3_0_, COMMITS2_.COMMIT_ID AS COMMIT_I1_0_, COMMITS2_.DATE AS DATE2_0_, COMMITS2_.MESSAGE AS MESSAGE3_0_, COMMITS2_.REPOSITORY_ID AS REPOSITO4_0_ FROM REPOSITORY REPOSITORY0_ CROSS JOIN USER USER1_ INNER JOIN COMMIT COMMITS2_ ON REPOSITORY0_.REPOSITORY_ID=COMMITS2_.REPOSITORY_ID WHERE REPOSITORY0_.OWNER_LOGIN=USER1_.USER_LOGIN AND REPOSITORY0_.REPOSITORY_ID=?"; expected "*, NOT, EXISTS, INTERSECTS, UNIQUE"; SQL statement:
select repository0_.repository_id as col_0_0_, repository0_.repository_name as col_1_0_, user1_.user_name as col_2_0_, . as col_3_0_, commits2_.commit_id as commit_i1_0_, commits2_.date as date2_0_, commits2_.message as message3_0_, commits2_.repository_id as reposito4_0_ from repository repository0_ cross join user user1_ inner join commit commits2_ on repository0_.repository_id=commits2_.repository_id where repository0_.owner_login=user1_.user_login and repository0_.repository_id=? [42001-200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:453)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
at org.h2.message.DbException.getSyntaxError(DbException.java:243)
at org.h2.command.Parser.getSyntaxError(Parser.java:1053)
[...]
我认为问题出在我正在尝试 select 一个 OneToMany
关系,因为当 selecting 所有者时我没有这个问题,因为我有一个 @JsonIgnore
注释和无限循环...
除了,在这种情况下,我需要 select 交易列表 :(
在此先感谢您的帮助!
您的 sql 查询中的错误是 r.commits
部分。它是一个值列表,sql 列仅接受 single (or scalar)
值类型,例如 number
、varchar
等
由于 Repository
和 Commit
实体之间的关系是 One-To-Many
关联,因此 r.commits
是一个值列表,因此 Hibernate 无法准备 sql声明。
您可以从 sql 查询中删除 r.commits 部分,它将起作用。
如果您想获取存储库的提交列表,您可以为此实现一个特定的方法。
像
public interface CommitRepository extends JpaRepository<Commit, Long> {
List<Commit> findAllByRepository(Repository repository);
}
您可以将要获取所有关联提交的 repository
对象传递给此方法。
此外,由于 Repository.repositoryId
是 Long
数据类型,因此您必须将 RepositoriesDB
定义更改为
public interface RepositoriesDB extends JpaRepository<Repository, Long>
这是我想要实现的目标:
Write a web service that gives the details of a repository: id, name, user name and list of commits.
需要以JSON
格式返回,例如:
{
"repository_id": "1",
"repository_name": "My repo",
"owner": "Noah",
"commits": [
"First commit",
"Second commit",
"Third commit"
]
}
您会发现数据库结构如下:
这是我的 CrudRepository
我正在尝试构建的查询:
public interface RepositoriesDB extends CrudRepository<Repository, String> {
@Query(value = "SELECT r.repositoryId, r.repositoryName, r.owner.userName, r.commits FROM Repository r WHERE r.repositoryId = :repoId")
List<Object[]> getRepo(@Param("repoId") long repoId);
}
我的 User
class :
@Entity
@NoArgsConstructor
@Data
public class User {
@NotNull
@Id
private String userLogin;
@NotBlank
@NotNull
private String userName;
@OneToMany(mappedBy = "owner", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JsonIgnore
private List<Repository> repositories;
}
我的 Repository
class :
@Entity
@NoArgsConstructor
@Data
public class Repository {
@NotNull
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long repositoryId;
@NotNull
@NotBlank
@Size(min = 3, max = 25)
private String repositoryName;
@OneToMany(mappedBy = "repository", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JsonIgnore
private List<Commit> commits;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "owner_login", nullable = false)
private User owner;
}
我的 Commit
class :
@Entity
@NoArgsConstructor
@Data
public class Commit {
@NotNull
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long commitId;
@NotBlank
@NotNull
private LocalDateTime date = LocalDateTime.now();
@NotNull
@NotBlank
@Size(min = 1, max = 255)
private String message;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "repository_id", nullable = false)
private Repository repository;
}
最后,这里是堆栈跟踪:
There was an unexpected error (type=Internal Server Error, status=500).
could not prepare statement; SQL [select repository0_.repository_id as col_0_0_, repository0_.repository_name as col_1_0_, user1_.user_name as col_2_0_, . as col_3_0_, commits2_.commit_id as commit_i1_0_, commits2_.date as date2_0_, commits2_.message as message3_0_, commits2_.repository_id as reposito4_0_ from repository repository0_ cross join user user1_ inner join commit commits2_ on repository0_.repository_id=commits2_.repository_id where repository0_.owner_login=user1_.user_login and repository0_.repository_id=?]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [select repository0_.repository_id as col_0_0_, repository0_.repository_name as col_1_0_, user1_.user_name as col_2_0_, . as col_3_0_, commits2_.commit_id as commit_i1_0_, commits2_.date as date2_0_, commits2_.message as message3_0_, commits2_.repository_id as reposito4_0_ from repository repository0_ cross join user user1_ inner join commit commits2_ on repository0_.repository_id=commits2_.repository_id where repository0_.owner_login=user1_.user_login and repository0_.repository_id=?]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:259)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551)
[...]
Caused by: org.hibernate.exception.SQLGrammarException: could not prepare statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:63)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
[...]
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "SELECT REPOSITORY0_.REPOSITORY_ID AS COL_0_0_, REPOSITORY0_.REPOSITORY_NAME AS COL_1_0_, USER1_.USER_NAME AS COL_2_0_, .[*] AS COL_3_0_, COMMITS2_.COMMIT_ID AS COMMIT_I1_0_, COMMITS2_.DATE AS DATE2_0_, COMMITS2_.MESSAGE AS MESSAGE3_0_, COMMITS2_.REPOSITORY_ID AS REPOSITO4_0_ FROM REPOSITORY REPOSITORY0_ CROSS JOIN USER USER1_ INNER JOIN COMMIT COMMITS2_ ON REPOSITORY0_.REPOSITORY_ID=COMMITS2_.REPOSITORY_ID WHERE REPOSITORY0_.OWNER_LOGIN=USER1_.USER_LOGIN AND REPOSITORY0_.REPOSITORY_ID=?"; expected "*, NOT, EXISTS, INTERSECTS, UNIQUE"; SQL statement:
select repository0_.repository_id as col_0_0_, repository0_.repository_name as col_1_0_, user1_.user_name as col_2_0_, . as col_3_0_, commits2_.commit_id as commit_i1_0_, commits2_.date as date2_0_, commits2_.message as message3_0_, commits2_.repository_id as reposito4_0_ from repository repository0_ cross join user user1_ inner join commit commits2_ on repository0_.repository_id=commits2_.repository_id where repository0_.owner_login=user1_.user_login and repository0_.repository_id=? [42001-200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:453)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
at org.h2.message.DbException.getSyntaxError(DbException.java:243)
at org.h2.command.Parser.getSyntaxError(Parser.java:1053)
[...]
我认为问题出在我正在尝试 select 一个 OneToMany
关系,因为当 selecting 所有者时我没有这个问题,因为我有一个 @JsonIgnore
注释和无限循环...
除了,在这种情况下,我需要 select 交易列表 :(
在此先感谢您的帮助!
您的 sql 查询中的错误是 r.commits
部分。它是一个值列表,sql 列仅接受 single (or scalar)
值类型,例如 number
、varchar
等
由于 Repository
和 Commit
实体之间的关系是 One-To-Many
关联,因此 r.commits
是一个值列表,因此 Hibernate 无法准备 sql声明。
您可以从 sql 查询中删除 r.commits 部分,它将起作用。
如果您想获取存储库的提交列表,您可以为此实现一个特定的方法。 像
public interface CommitRepository extends JpaRepository<Commit, Long> {
List<Commit> findAllByRepository(Repository repository);
}
您可以将要获取所有关联提交的 repository
对象传递给此方法。
此外,由于 Repository.repositoryId
是 Long
数据类型,因此您必须将 RepositoriesDB
定义更改为
public interface RepositoriesDB extends JpaRepository<Repository, Long>