I have two entities user and movie. I want to display movies for the users. Users are going to see the movies they added. I connected these two enetities with manyToMany and i am trying to get the data but i am having this error.
2021-05-27 01:01:16.109 ERROR 4064 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.QueryException: could not resolve property: user of: com.moviePage.movieP.Entities.Movie [from com.moviePage.movieP.Entities.Movie m join m.user u where u.id = 1]; nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: could not resolve property: user of: com.moviePage.movieP.Entities.Movie [from com.moviePage.movieP.Entities.Movie m join m.user u where u.id = 1]] with root cause
org.hibernate.QueryException: could not resolve property: user of: com.moviePage.movieP.Entities.Movie
at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:77) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:71) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:2038) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.hql.internal.ast.tree.FromElementType.getPropertyType(FromElementType.java:412) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.hql.internal.ast.tree.FromElement.getPropertyType(FromElement.java:520) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.hql.internal.ast.tree.DotNode.getDataType(DotNode.java:695) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.hql.internal.ast.tree.DotNode.prepareLhs(DotNode.java:269) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.hql.internal.ast.tree.DotNode.resolve(DotNode.java:209) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:114) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:109) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
...
User
#Entity
#Table(name="user")
public class User {
#Id
#Column(name="user_id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#NotNull(message="Enter first name")
#Column(name="name")
private String name;
#ManyToMany
#JoinTable(
name="user_movie",
joinColumns =#JoinColumn(name="user_id"),
inverseJoinColumns=#JoinColumn(name="movie_id"))
private Set<Movie> movies;
Movie
#Entity
#Table(name="movie")
public class Movie {
#Id
#Column(name="movie_id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#Column(name="title")
private String title;
#Lob
#Column(name="summary")
private String summary;
#ManyToMany(mappedBy = "movies")
private Set<User> users;
getMovies => i put this in data access layer and call it from the controller and from the controller i am going to send the movies to the html page
public List<Movie> getMovies(int id) {
Session session = entityManager.unwrap(Session.class);
String hql = "from Movie m join m.user u where u.id = "+ String.valueOf(id);
List<Movie> movies = session.createQuery(hql).list();
System.out.println(movies);//tried to look what it will return
return movies;
}
//List<Movie> movies = session.createQuery("from Movie m join m.user u where u.user_id=:user_id").setParameter("id", id).getResultList();
i have tried these two and both produce the same error. I couldn't understand the error please help:)
You probably want:
String hql = "from Movie m join m.users u where u.id = "+ String.valueOf(id);
Related
enter image description here
this img is user table and example tuple
here,
I want to use sql query "SELECT MAX(KEY_NAME) FROM USER;" and right here
enter image description here
So in java, I wrote jpa query but I met ERROR 16148
2023-02-01 20:58:51.668 ERROR 16148 --- [nio-8080-exec-7] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Type specified for TypedQuery [gdsc.toypj.dutchpayit.domain.User] is incompatible with query return type [class java.lang.Long]; nested exception is java.lang.IllegalArgumentException: Type specified for TypedQuery [gdsc.toypj.dutchpayit.domain.User] is incompatible with query return type [class java.lang.Long]] with root cause
here my source
UserRepository.java
public User findOneUser() {
return em.createQuery("select MAX(r.id) from User r", User.class)
.getSingleResult();
}
User.java
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "key_name")
private Long id;
private String name;
#OneToMany(mappedBy = "user",cascade = CascadeType.ALL)
private List<Menu> menuList = new ArrayList<>();
#OneToMany(mappedBy = "user",cascade = CascadeType.ALL)
private List<People> peopleList = new ArrayList<>();
public static User addUser(String name){
User user = new User();
user.setName(name);
return user;
}
UserService.java
#Transactional
public User OneUser(){
User user = userRepository.findOneUser();
return user;
}
UserController.java
#GetMapping("/get/one")
public ResponseEntity getOneUser(){
User user = userService.OneUser();
return ResponseEntity.status(HttpStatus.OK).body(new SuccessResponse(200,user));
}
I've been trying more than 3 hours..
in UserRepository.java, I tried them and error in everything.
em.createQuery("select MAX(r.Key_name) from User r", User.class)
em.createQuery("select id from User", User.class)
oh this is worked
return em.createQuery("select r from User r", User.class)
.getResultList();
why only "select r" is working I don't know!!!!
The error comes from the TypedQuery defined to return the User object.
You can try and change the TypedQuery to Long or create another query that will return the User as an object.
You can go with something similar like this:
select r from User r where r.id = (select MAX(r.id) from User r)
Here is what I'm trying to achieve :
Write a web service that gives the details of a repository: id, name, user name and
list of commits.
💡 It needs to be returned as a JSON format, for example :
{
"repository_id": "1",
"repository_name": "My repo",
"owner": "Noah",
"commits": [
"First commit",
"Second commit",
"Third commit"
]
}
You will find the database structure below :
Here is my CrudRepository with the query I am trying to build:
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);
}
My 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;
}
My 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;
}
My 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;
}
And finally, here is the stacktrace :
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)
[...]
I believe the problem comes from the fact that I'm trying to select a OneToMany relation, since I don't have this issue when selecting the owner because I have an #JsonIgnore annotation and infinite loops...
Except, in this case, I NEED to select the list of transaction :(
Thanks in advance for your help !
The error in your sql query is the r.commits part. It is a list of values and sql column accept only a single (or scalar) value type like number, varchar etc
Since the relation between Repository and Commit entities isOne-To-Many association so r.commits is a list of values so Hibernate fails to prepare the sql statement.
You can remove the r.commits part from your sql query and it will works.
If you would like to get the list of commits for your repository, you can implement a specefic method for that.
Something like
public interface CommitRepository extends JpaRepository<Commit, Long> {
List<Commit> findAllByRepository(Repository repository);
}
you can pass to this method the repository object that you want to get all the associated commits.
Also, since the Repository.repositoryId is Long data type so you have to change the RepositoriesDB defenition to
public interface RepositoriesDB extends JpaRepository<Repository, Long>
I'm working on a Spring Boot project using JPA to connect to my DB. I wan to make a native query to select some specific fields but it doesn't allow me to do. For example, I want to get only id, firstName, lastName and phoneNumber of a customer But it will throws me error like,
The column name current_access_token was not found in this ResultSet.
Here is my query code in the JPA repository,
#Query(value = "SELECT c.id, c.phone_number, c.firstname, c.lastname FROM tbl_customers c JOIN tbl_subscriptions s ON c.id = s.customer_id WHERE s.role = 'member' AND s.deleted_at IS NULL", nativeQuery = true)
List<Customer> findMemberByRole(String role);
Here is my Cutomer.java
#Getter
#Setter
#Accessors(chain=true)
#NoArgsConstructor
#AllArgsConstructor
#ToString
#Entity
#Table(name = "tbl_customers")
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(unique = true)
private Long id;
#Column(nullable = false, name = "phone_number")
private String phoneNumber;
private String firstname;
private String lastname;
#Column(name = "current_access_token")
private String currentAccessToken;
#Column(name = "consent_accepted")
private Boolean consentAccepted;
...
...
}
How can I avoid or ignore unwanted columns? Thanks a lot for helps.
If you really want to return only 4 columns from the customer table, then the signature you want to use here is List<Object[]>:
#Query(value = "SELECT c.id, c.phone_number, c.firstname, c.lastname FROM tbl_customers c JOIN tbl_subscriptions s ON c.id = s.customer_id WHERE s.role = 'member' AND s.deleted_at IS NULL", nativeQuery = true)
List<Object[]> findMemberByRole(String role);
Then, when accessing your result set, you would use something like:
List<Object[]> resultSet = findMemberByRole("admin");
for (Object[] rs : resultSet) {
Long id = (Long) rs[0];
String phoneNumber = (String) rs[1];
String firstName = (String) rs[2];
String lastName = (String) rs[3];
}
I use: Spring Boot, Spring Data, and H2 (in-memory) DataBase.
DB TABLES:
CREATE TABLE user
(
id INT AUTO_INCREMENT,
name VARCHAR(250) NOT NULL,
age INT NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE article
(
id INT AUTO_INCREMENT,
text TEXT NOT NULL,
color ENUM ('red', 'green', 'blue', 'yellow', 'pink') NOT NULL,
user_id INT,
PRIMARY KEY (id),
FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE CASCADE ON UPDATE CASCADE
);
In ArticleRepository exploited such query:
SELECT u.name, a.user_id, count() FROM user AS u INNER JOIN article AS a ON u.id = a.user_id GROUP BY a.user_id HAVING COUNT() > 3;
#Repository
public interface ArticleRepository extends JpaRepository<Article, Integer> {
#Query(value = "SELECT u.name, a.user_id, count(*) FROM user AS u INNER JOIN article AS a ON u.id = a.user_id GROUP BY a.user_id HAVING COUNT(*) > 3", nativeQuery = true)
List<Article> findUserNamesByArticlesCountMoreThan();
}
After request I receive the error:
In Postman:
"error": "Internal Server Error", "message": "could not execute query;
SQL [SELECT u.name, a.user_id, count(text) FROM user AS u INNER JOIN
article AS a ON u.id = a.user_id GROUP BY a.user_id HAVING COUNT(*) >
3]; nested exception is org.hibernate.exception.SQLGrammarException:
could not execute query",
In IntelliJ Idea:
02:54:24.681 [http-nio-9090-exec-1] WARN SqlExceptionHelper - SQL
Error: 42122, SQLState: 42S22 02:54:24.681 [http-nio-9090-exec-1]
ERROR SqlExceptionHelper - Column "id" not found [42122-197]
02:54:24.703 [http-nio-9090-exec-1] ERROR [dispatcherServlet] -
Servlet.service() for servlet [dispatcherServlet] in context with path
[] threw exception [Request processing failed; nested exception is
org.springframework.dao.InvalidDataAccessResourceUsageException: could
not execute query; SQL [SELECT u.name, a.user_id, count(text) FROM
user AS u INNER JOIN article AS a ON u.id = a.user_id GROUP BY
a.user_id HAVING COUNT(*) > 3]; nested exception is
org.hibernate.exception.SQLGrammarException: could not execute query]
with root cause org.h2.jdbc.JdbcSQLException: Column "id" not found
[42122-197] at
org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
at org.h2.message.DbException.get(DbException.java:179) at
org.h2.message.DbException.get(DbException.java:155) at
org.h2.jdbc.JdbcResultSet.getColumnIndex(JdbcResultSet.java:3148) at
org.h2.jdbc.JdbcResultSet.get(JdbcResultSet.java:3247) at
org.h2.jdbc.JdbcResultSet.getInt(JdbcResultSet.java:346)..............
Help me to resolve this problem, and find a mistake.
Entities:
#Entity
#Data
#NoArgsConstructor
#AllArgsConstructor
#Table(name = "article")
public class Article {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, nullable = false)
private Integer id;
#Column(name = "text", nullable = false)
private String text;
#Column(name = "color", nullable = false, unique = true)
#Enumerated(EnumType.STRING)
private Color color;
#JsonIgnore
#ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL )
#JoinColumn(name = "user_id", referencedColumnName="id")
private User user;
}
.
#Entity
#Data
#NoArgsConstructor
#AllArgsConstructor
#ToString(exclude = "articles")
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false)
private Integer id;
#Column(name = "name", nullable = false)
private String name;
#Column(name = "age", nullable = false)
private Integer age;
#JsonIgnore
#OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
private Set<Article> articles;
}
Service:
#Service
public class ArticleService {
private ArticleRepository articleRepository;
#Autowired
public ArticleService(ArticleRepository articleRepository) {
this.articleRepository = articleRepository;
}
public List<Article> findAllUserNamesByArticlesMoreThan() {
return articleRepository.findUserNamesByArticlesCountMoreThan(); }}
ArticleDtoService:
#Service
public class ArticleDtoService {
private ArticleService articleService;
#Autowired
public ArticleDtoService(ArticleService articleService) {
this.articleService = articleService;
}
public ResponseEntity<List<ArticleDto>> getAllUserNamesByArticlesMoreThan() {
List<Article> articles = articleService.findAllUserNamesByArticlesMoreThan();
Link link = linkTo(methodOn(ArticleController.class).getAllUserNamesListByArticlesMoreThan()).withSelfRel();
return new ResponseEntity<>(createArticleDtoList(articles, link), HttpStatus.OK); }}
ArticleController:
#RestController
public class ArticleController {
private final ArticleDtoService articleDtoService;
#Autowired
public ArticleController(ArticleDtoService articleDtoService) {
this.articleDtoService = articleDtoService;
}
#GetMapping(value = "/api/articles/count")
public ResponseEntity<List<ArticleDto>> getAllUserNamesListByArticlesMoreThan() {
return articleDtoService.getAllUserNamesByArticlesMoreThan(); }}
ArticleDto:
public class ArticleDto extends ResourceSupport {
public Article article;
public ArticleDto(Article article, Link selfLink) {
this.article = article;
add(selfLink); }}
I'm using single table inheritance and trying to fetch entities by their discriminator column but I'm getting errors ...
I don't have the discriminator value as a field in the class.
Here's my code :
User Class
#Entity
#Table(name = "MT_User")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "userType", discriminatorType = DiscriminatorType.STRING)
#DiscriminatorValue("CLASSIC")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int uid;
public String imageFileName;
private String pseudo;
private String email;
private String password;
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "MT_User_Playlist", joinColumns = #JoinColumn(name = "uid"), inverseJoinColumns = #JoinColumn(name = "tlid"))
private List<Playlist> playlists;
...
}
Admin Class
#Entity
#DiscriminatorValue("ADMIN")
public class Admin extends User implements SuperUser {
//no fields
...
}
User Repository
public interface UserRepository extends CrudRepository<User, Integer> {
User findByPseudo(String pseudo);
User findByEmail(String email);
void deleteByPseudo(String pseudo);
void deleteByEmail(String email);
List<User> findByUserType(String userType);
#Query("from mt_user where user_type=ADMIN")
List<User> findAdmins();
#Query("from mt_user where user_type=ADMIN and pseudo=?1")
User findAdminByPseudo(String pseudo);
}
Here are the errors I get :
Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: mt_user is not mapped [from mt_user where user_type=ADMIN and pseudo=?1]
Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: mt_user is not mapped [from mt_user where user_type=ADMIN]
Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List org.ThePouil.projects.mytunes.DAO.UserRepository.findByUserType(java.lang.String)! No property userType found for type User!
Thanks for your help !
:: EDIT ::
This solved my problems :
#Query("from User")
List<User> findUsers();
#Query("from Admin")
List<User> findAdmins();
#Query("from Admin where pseudo=?1")
User findAdminByPseudo(String pseudo);
You should use class name of your #Entity and not tables names in your queries. It should be from Admin or from User.