英文:
How to get selective column in spring boot JPA?
问题
以下是您要翻译的内容:
我是Spring Boot的新手。
我有两个实体 Invite 和 User。
@Entity
public class Invite {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name="email")
private String email_id;
private String mobile;
private String pincode;
private String name;
private String status;
private Date created_on;
private Date updated_on;
//getters and setters
}
@Entity
public class User {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private int id;
@OneToOne
private Invite invite;
private String firstName;
private String LastName;
@JsonIgnore
private String password;
private Date created_on;
private Date updated_on;
// getters and setters
}
我想要以下数据:
+---------+---------------------------------------------+
| id | firstName email_id mobile |
+---------+---------------------------------------------+
| | | | |
| 1 | Ram | s@mail.com | 1111111111 |
| | | | |
+---------+---------+------------+----------------------+
因此,我在 UserRepository 中创建了以下查询:
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
@Query("select u.id, u.firstName, i.email_id, i.mobile from User u inner join u.invite i")
public List<User> getUserDetails();
}
因此,我得到以下错误:
Failed to convert from type [java.lang.Object[]] to type [@org.springframework.data.jpa.repository.Query com.example.jpa.JPA.entity.User] for value
我知道这是因为返回值的类型是 Object 数组,而我试图将其转换为 User。
请问您能否提供一种在不创建额外 DTO 类或接口的情况下获取任何数据的方法?
英文:
I am new to spring boot.
I have two entities Invite and User.
@Entity
public class Invite {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name="email")
private String email_id;
private String mobile;
private String pincode;
private String name;
private String status;
private Date created_on;
private Date updated_on;
//gettes and setters
}
@Entity
public class User {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private int id;
@OneToOne
private Invite invite;
private String firstName;
private String LastName;
@JsonIgnore
private String password;
private Date created_on;
private Date updated_on;
// getters and setters
}
I want the following data
+---------+---------------------------------------------+
| id | firstName email_id mobile |
+-------------------+------------+----------------------+
| | | | |
| 1 |Ram | s@mail.com | 1111111111 |
| | | | |
+---------+---------+------------+----------------------+
So I have created the below query in UserRepository:
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
@Query("select u.id,u.firstName,i.email_id, i.mobile from User u inner join u.invite i")
public List<User> getUserDetails();
}
So I am getting the below error -
Failed to convert from type [java.lang.Object[]] to type [@org.springframework.data.jpa.repository.Query com.example.jpa.JPA.entity.User] for value
I know it's because the return value is of type Object and I am trying to get it into user.
Could you please give me a way to get any data without creating extra DTO classes or interface?
答案1
得分: 5
很好,你已经知道问题所在。
@Query("select u.id,u.firstName,i.email_id, i.mobile from User u inner join u.invite i")
List<User> getUserDetails();
你选择了几列,但要求 Data-Jpa 返回一个 User 对象的列表。
所以你首先需要理解 JPA 规范关于使用 JPQL 的内容。
-
select u from User u where u.id = :id
-> 这将返回一个User
类型对象的列表。
该查询在原生 SQL 中是:SELECT * FROM USER WHERE ID = "{传入的任何值}";
-
select u.username from User u where u.id = :id"
-> 这只返回用户名,假设用户名是字符串类型。因此,返回对象类型是 String 类型,如果您使用 TypedQuery,或者如果您使用 Query,则返回的是 Object。相应生成的 SQL 是SELECT u.USERNAME FROM USER u WHERE u.id = {id}
-
select u.id, u.username from User u where u.id = :id
-> 这将返回 Object[]。当您需要 DTO 投影以将其映射到您想要的适当类型时使用。
通过原生的 JPA 实现,您可以使用 DTO 投影 或 查询投影
我通常使用 JPA 规范中的 DTO 投影,不使用查询投影,因此我提供了一个 DTO 投影的示例,但是上述文档如果阅读过会对如何使用每个抽象/特性提供很好的参考。
- 定义一个表示 DTO 的类,我考虑的包名是:com.example。包名很重要,因为您需要完整的类名来在 JPQL 中引用
package com.example;
class UserDTO {
int id;
String firstName;
String email_id;
String mobile;
// 必须有全参构造函数
public UserDTO(int id, String firstName, String email_id, String mobile) {
// 赋值操作
}
// getters 和 setters
}
在 Repository 中:
@Query("select new com.example.UserDTO(u.id,u.firstName,i.email_id, i.mobile) from User u inner join u.invite i")
List<UserDTO> getUserDetails();
最重要的是:new 完整的类名(您检索的所有列)
这就是您如何使用 JPQL 和 Data Jpa Repository 进行 DTO 投影。
英文:
Its great you already know what the issue is.
@Query("select u.id,u.firstName,i.email_id, i.mobile from User u inner join u.invite i")
List<User> getUserDetails();
You are selecting a few columns but asking Data-Jpa to return you back with the a List of User Objects.
So you need to understand first, what JPA specification says about using JPQL.
-
select u from User u where u.id = :id
-> this returns a List ofUser
type Objects
This query in native is :SELECT * FROM USER WHERE ID = "{whatever value you passed}";
-
select u.username from User u where u.id = :id"
-> this returns just the username, which lets say is a String type. So the return object type is of the String type in case you using TypedQuery or Object is returned in case you using Query . The corresponding SQL generated isSELECT u.USERNAME FROM USER u WHERE u.id = {id}
-
select u.id, u.username from User u where u.id = :id
-> this returns Object[]. This is when you need the DTO projection to map it to a proper Type of what you want.
With native JPA implementations you can use DTO Projection or Query Projection
I mostly use DTO Projection from JPA spec ad not use Query Projection, so I am giving an example of DTO projection, but above documents if gone through gives a good reference how to work with each abstraction/feature.
- Define a class to represent the DTO and package I am taking into consideration: com.example. Package name is important since you need the full class name for reference in JPQL
package com.example;
class UserDTO {
int id;
String firstName,
String email_id;
String mobile;
//All args constructor is needed and madatory
public User(int id, String firstName, String email_id, String mobile) {
// assignments
}
// getters and setters
}
In the Repository:
@Query("select new com.example.UserDTO(u.id,u.firstName,i.email_id, i.mobile) from User u inner join u.invite i")
List<UserDTO> getUserDetails();
The most important thing being : new fully-qualifed-classname(all columns you are fetching)
This is how you use DTO projection with JPQL and Data Jpa Repository.
答案2
得分: 1
在User
类中编写一个构造函数,用于选择性地初始化列,并在查询中使用。确保在Invite
类中也使用了一个构造函数来初始化email_id
和mobile
,并在User
的构造函数中使用它。
@Query("select new com.example.jpa.JPA.entity.User(u.id, u.firstName, i.email_id, i.mobile) from User u inner join u.invite i")
public List<User> getUserDetails();
// 在User类和Invite类中使用这个构造函数
public User(int id, String firstName, String email_id, String mobile) {
// 分配id和firstName
// 调用Invite类的构造函数
}
public Invite(String email_id, String mobile) {
// 分配email_id和mobile
}
这是翻译好的部分,不包含额外的内容或问题回答。
英文:
Write a constructor in User
class for your selective column and use in query. Make sure you are also using a constructor in Invite
class for email_id
and mobile
and use it inside constructor in User.
@Query("select new com.example.jpa.JPA.entity.User(u.id,u.firstName,i.email_id, i.mobile) from User u inner join u.invite i")
public List<User> getUserDetails();
Use this constructor in User and Invite class
public User(int id, String firstName, String email_id, String mobile) {
// assign id and firstName
// call invite class constuctor
}
public Invite(String email_id, String mobile) {
// assign email_id and mobile
}
答案3
得分: 1
如果您想在查询结果中仅选择特定字段或自定义查询结果,您可以简单地使用JPA投影(Projection)
。创建一个带有相关属性方法的接口。
英文:
If you want to have selected fields in query result or customize query result, you can simply use jpa Projection
. create an interface with related property method
答案4
得分: -1
尝试这个...这对我有效:
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultNamingStrategy
这个需要添加到application.properties中。
英文:
try this ..this work for me :
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultNamingStrategy
this is to be added in application.properties
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论