Query result in JSON format (key value pair) on using @Query annotation in Spring Boot, Hibernate









up vote
1
down vote

favorite












My Controller



@GetMapping(value="/getAllDetails")
public List<PriceListEntity> getAllDetails()
return MyRepository.getAllDetails();



My Repository



@Repository
public interface MyRepository extends CrudRepository<TestNativeQ, String>
@Query( value="SELECT qplt.name price_list_name, qplab.status_code, qplab.start_date, (SELECT charge_definition_code FROM oalfsaas_repl.QP_CHARGE_DEFINITIONS_B WHERE charge_definition_id=qplab.charge_definition_id ) chargedefinitioncode "
+ "FROM PriceListEntity qplab, PriceListLineEntity qplt "
+ " WHERE qplab.price_list_id =qplt.price_list_id ", nativeQuery = false)
public List<PriceListEntity> getAllDetails();



Actual Result:



["ABC", "DEF", "15/05/2018", "XXZ"]


Expected Result



[name: "ABC", statuscode: "DEF", startDate: "15/05/2018", chargedefintioncode: "XXZ"]


The Query has join with more than one table and also subquery at column level.










share|improve this question























  • How do you get this ouput? With sysout?
    – NiVeR
    Nov 10 at 13:24










  • No, It is on calling this path "/getAllDetails".
    – Manoj Kumar
    Nov 10 at 14:18










  • I suppose you are using jackson for json manipulation. There can't be any problem there. Try to print the data before returning it in the api, to see if it is actually like the one you posted here.
    – NiVeR
    Nov 10 at 14:23














up vote
1
down vote

favorite












My Controller



@GetMapping(value="/getAllDetails")
public List<PriceListEntity> getAllDetails()
return MyRepository.getAllDetails();



My Repository



@Repository
public interface MyRepository extends CrudRepository<TestNativeQ, String>
@Query( value="SELECT qplt.name price_list_name, qplab.status_code, qplab.start_date, (SELECT charge_definition_code FROM oalfsaas_repl.QP_CHARGE_DEFINITIONS_B WHERE charge_definition_id=qplab.charge_definition_id ) chargedefinitioncode "
+ "FROM PriceListEntity qplab, PriceListLineEntity qplt "
+ " WHERE qplab.price_list_id =qplt.price_list_id ", nativeQuery = false)
public List<PriceListEntity> getAllDetails();



Actual Result:



["ABC", "DEF", "15/05/2018", "XXZ"]


Expected Result



[name: "ABC", statuscode: "DEF", startDate: "15/05/2018", chargedefintioncode: "XXZ"]


The Query has join with more than one table and also subquery at column level.










share|improve this question























  • How do you get this ouput? With sysout?
    – NiVeR
    Nov 10 at 13:24










  • No, It is on calling this path "/getAllDetails".
    – Manoj Kumar
    Nov 10 at 14:18










  • I suppose you are using jackson for json manipulation. There can't be any problem there. Try to print the data before returning it in the api, to see if it is actually like the one you posted here.
    – NiVeR
    Nov 10 at 14:23












up vote
1
down vote

favorite









up vote
1
down vote

favorite











My Controller



@GetMapping(value="/getAllDetails")
public List<PriceListEntity> getAllDetails()
return MyRepository.getAllDetails();



My Repository



@Repository
public interface MyRepository extends CrudRepository<TestNativeQ, String>
@Query( value="SELECT qplt.name price_list_name, qplab.status_code, qplab.start_date, (SELECT charge_definition_code FROM oalfsaas_repl.QP_CHARGE_DEFINITIONS_B WHERE charge_definition_id=qplab.charge_definition_id ) chargedefinitioncode "
+ "FROM PriceListEntity qplab, PriceListLineEntity qplt "
+ " WHERE qplab.price_list_id =qplt.price_list_id ", nativeQuery = false)
public List<PriceListEntity> getAllDetails();



Actual Result:



["ABC", "DEF", "15/05/2018", "XXZ"]


Expected Result



[name: "ABC", statuscode: "DEF", startDate: "15/05/2018", chargedefintioncode: "XXZ"]


The Query has join with more than one table and also subquery at column level.










share|improve this question















My Controller



@GetMapping(value="/getAllDetails")
public List<PriceListEntity> getAllDetails()
return MyRepository.getAllDetails();



My Repository



@Repository
public interface MyRepository extends CrudRepository<TestNativeQ, String>
@Query( value="SELECT qplt.name price_list_name, qplab.status_code, qplab.start_date, (SELECT charge_definition_code FROM oalfsaas_repl.QP_CHARGE_DEFINITIONS_B WHERE charge_definition_id=qplab.charge_definition_id ) chargedefinitioncode "
+ "FROM PriceListEntity qplab, PriceListLineEntity qplt "
+ " WHERE qplab.price_list_id =qplt.price_list_id ", nativeQuery = false)
public List<PriceListEntity> getAllDetails();



Actual Result:



["ABC", "DEF", "15/05/2018", "XXZ"]


Expected Result



[name: "ABC", statuscode: "DEF", startDate: "15/05/2018", chargedefintioncode: "XXZ"]


The Query has join with more than one table and also subquery at column level.







json spring-boot spring-data-jpa dto jsonresponse






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 at 5:45

























asked Nov 10 at 13:23









Manoj Kumar

176




176











  • How do you get this ouput? With sysout?
    – NiVeR
    Nov 10 at 13:24










  • No, It is on calling this path "/getAllDetails".
    – Manoj Kumar
    Nov 10 at 14:18










  • I suppose you are using jackson for json manipulation. There can't be any problem there. Try to print the data before returning it in the api, to see if it is actually like the one you posted here.
    – NiVeR
    Nov 10 at 14:23
















  • How do you get this ouput? With sysout?
    – NiVeR
    Nov 10 at 13:24










  • No, It is on calling this path "/getAllDetails".
    – Manoj Kumar
    Nov 10 at 14:18










  • I suppose you are using jackson for json manipulation. There can't be any problem there. Try to print the data before returning it in the api, to see if it is actually like the one you posted here.
    – NiVeR
    Nov 10 at 14:23















How do you get this ouput? With sysout?
– NiVeR
Nov 10 at 13:24




How do you get this ouput? With sysout?
– NiVeR
Nov 10 at 13:24












No, It is on calling this path "/getAllDetails".
– Manoj Kumar
Nov 10 at 14:18




No, It is on calling this path "/getAllDetails".
– Manoj Kumar
Nov 10 at 14:18












I suppose you are using jackson for json manipulation. There can't be any problem there. Try to print the data before returning it in the api, to see if it is actually like the one you posted here.
– NiVeR
Nov 10 at 14:23




I suppose you are using jackson for json manipulation. There can't be any problem there. Try to print the data before returning it in the api, to see if it is actually like the one you posted here.
– NiVeR
Nov 10 at 14:23












1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted










Your are actually doing a projection with your select which does not return any specific object but a tuple which is an array of objects you select in your query. Whatever way the JSON is made there are no names just values.



You need to create a DTO to hold the values you want to pass by names in your JSON.



A minimal example, having a simple entity like:



@Entity
@Getter
@RequiredArgsConstructor
public class TestClass
@Id
@GeneratedValue
private Long id;

@NonNull
private String a,b,c;



and willing to pass -for example - only a & b there might be DTO like:



@RequiredArgsConstructor
public class TupleDto
@NonNull
private String a,b;



and in your case some sort of PriceListDetailsDto



the repository might be declared like:



public interface TestClassRepository extends CrudRepository<TestClass, Long> 

@Query(value="SELECT new org.example.TupleDto(tc.a, tc.b) FROM TestClass tc")
List<TupleDto> fetchAB();




NOTE: in above that there is used operator new and a full path to the entity constructor.



This way Spring repository knows how to assign selected fields and when making a JSON from this DTO will result having fields with names (names in DTO).



The new operator in JPQL is just calling new in java- So any row data a,b,c can be used to construct Java object with that object's class constructor accepting same parameter amount and types (and in the same order) so liie new MyEntityObject(a,b,c).



NOTE ALSO: in this simple case the original entity could have been used as DTO if it was modified to allow null value in c and adding corresponding constructor. In your case where your tuple is constructed from many tables you need to create a DTO to hold those values.






share|improve this answer






















  • Thanks for answering, can this approach be used when there is subquery at the column level. Also what is the BaseEntity here ?
    – Manoj Kumar
    Nov 12 at 5:46











  • @ManojKumar I am ont sure what you mean by columnn level. But will add a small update to answer at a moment. The base entity just had the @Id
    – pirho
    Nov 12 at 5:57











  • The fourh column is the subquery
    – Manoj Kumar
    Nov 12 at 6:20










  • @ManojKumar I see. Just add the columns that subquery returns to you DTO & its constructor. In a result set it is still a one or more columns. So if subquery is like select charge_definition_code add yet that charge_definition_code to your DTO and its constructor.
    – pirho
    Nov 12 at 6:24











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53239376%2fquery-result-in-json-format-key-value-pair-on-using-query-annotation-in-sprin%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote



accepted










Your are actually doing a projection with your select which does not return any specific object but a tuple which is an array of objects you select in your query. Whatever way the JSON is made there are no names just values.



You need to create a DTO to hold the values you want to pass by names in your JSON.



A minimal example, having a simple entity like:



@Entity
@Getter
@RequiredArgsConstructor
public class TestClass
@Id
@GeneratedValue
private Long id;

@NonNull
private String a,b,c;



and willing to pass -for example - only a & b there might be DTO like:



@RequiredArgsConstructor
public class TupleDto
@NonNull
private String a,b;



and in your case some sort of PriceListDetailsDto



the repository might be declared like:



public interface TestClassRepository extends CrudRepository<TestClass, Long> 

@Query(value="SELECT new org.example.TupleDto(tc.a, tc.b) FROM TestClass tc")
List<TupleDto> fetchAB();




NOTE: in above that there is used operator new and a full path to the entity constructor.



This way Spring repository knows how to assign selected fields and when making a JSON from this DTO will result having fields with names (names in DTO).



The new operator in JPQL is just calling new in java- So any row data a,b,c can be used to construct Java object with that object's class constructor accepting same parameter amount and types (and in the same order) so liie new MyEntityObject(a,b,c).



NOTE ALSO: in this simple case the original entity could have been used as DTO if it was modified to allow null value in c and adding corresponding constructor. In your case where your tuple is constructed from many tables you need to create a DTO to hold those values.






share|improve this answer






















  • Thanks for answering, can this approach be used when there is subquery at the column level. Also what is the BaseEntity here ?
    – Manoj Kumar
    Nov 12 at 5:46











  • @ManojKumar I am ont sure what you mean by columnn level. But will add a small update to answer at a moment. The base entity just had the @Id
    – pirho
    Nov 12 at 5:57











  • The fourh column is the subquery
    – Manoj Kumar
    Nov 12 at 6:20










  • @ManojKumar I see. Just add the columns that subquery returns to you DTO & its constructor. In a result set it is still a one or more columns. So if subquery is like select charge_definition_code add yet that charge_definition_code to your DTO and its constructor.
    – pirho
    Nov 12 at 6:24















up vote
1
down vote



accepted










Your are actually doing a projection with your select which does not return any specific object but a tuple which is an array of objects you select in your query. Whatever way the JSON is made there are no names just values.



You need to create a DTO to hold the values you want to pass by names in your JSON.



A minimal example, having a simple entity like:



@Entity
@Getter
@RequiredArgsConstructor
public class TestClass
@Id
@GeneratedValue
private Long id;

@NonNull
private String a,b,c;



and willing to pass -for example - only a & b there might be DTO like:



@RequiredArgsConstructor
public class TupleDto
@NonNull
private String a,b;



and in your case some sort of PriceListDetailsDto



the repository might be declared like:



public interface TestClassRepository extends CrudRepository<TestClass, Long> 

@Query(value="SELECT new org.example.TupleDto(tc.a, tc.b) FROM TestClass tc")
List<TupleDto> fetchAB();




NOTE: in above that there is used operator new and a full path to the entity constructor.



This way Spring repository knows how to assign selected fields and when making a JSON from this DTO will result having fields with names (names in DTO).



The new operator in JPQL is just calling new in java- So any row data a,b,c can be used to construct Java object with that object's class constructor accepting same parameter amount and types (and in the same order) so liie new MyEntityObject(a,b,c).



NOTE ALSO: in this simple case the original entity could have been used as DTO if it was modified to allow null value in c and adding corresponding constructor. In your case where your tuple is constructed from many tables you need to create a DTO to hold those values.






share|improve this answer






















  • Thanks for answering, can this approach be used when there is subquery at the column level. Also what is the BaseEntity here ?
    – Manoj Kumar
    Nov 12 at 5:46











  • @ManojKumar I am ont sure what you mean by columnn level. But will add a small update to answer at a moment. The base entity just had the @Id
    – pirho
    Nov 12 at 5:57











  • The fourh column is the subquery
    – Manoj Kumar
    Nov 12 at 6:20










  • @ManojKumar I see. Just add the columns that subquery returns to you DTO & its constructor. In a result set it is still a one or more columns. So if subquery is like select charge_definition_code add yet that charge_definition_code to your DTO and its constructor.
    – pirho
    Nov 12 at 6:24













up vote
1
down vote



accepted







up vote
1
down vote



accepted






Your are actually doing a projection with your select which does not return any specific object but a tuple which is an array of objects you select in your query. Whatever way the JSON is made there are no names just values.



You need to create a DTO to hold the values you want to pass by names in your JSON.



A minimal example, having a simple entity like:



@Entity
@Getter
@RequiredArgsConstructor
public class TestClass
@Id
@GeneratedValue
private Long id;

@NonNull
private String a,b,c;



and willing to pass -for example - only a & b there might be DTO like:



@RequiredArgsConstructor
public class TupleDto
@NonNull
private String a,b;



and in your case some sort of PriceListDetailsDto



the repository might be declared like:



public interface TestClassRepository extends CrudRepository<TestClass, Long> 

@Query(value="SELECT new org.example.TupleDto(tc.a, tc.b) FROM TestClass tc")
List<TupleDto> fetchAB();




NOTE: in above that there is used operator new and a full path to the entity constructor.



This way Spring repository knows how to assign selected fields and when making a JSON from this DTO will result having fields with names (names in DTO).



The new operator in JPQL is just calling new in java- So any row data a,b,c can be used to construct Java object with that object's class constructor accepting same parameter amount and types (and in the same order) so liie new MyEntityObject(a,b,c).



NOTE ALSO: in this simple case the original entity could have been used as DTO if it was modified to allow null value in c and adding corresponding constructor. In your case where your tuple is constructed from many tables you need to create a DTO to hold those values.






share|improve this answer














Your are actually doing a projection with your select which does not return any specific object but a tuple which is an array of objects you select in your query. Whatever way the JSON is made there are no names just values.



You need to create a DTO to hold the values you want to pass by names in your JSON.



A minimal example, having a simple entity like:



@Entity
@Getter
@RequiredArgsConstructor
public class TestClass
@Id
@GeneratedValue
private Long id;

@NonNull
private String a,b,c;



and willing to pass -for example - only a & b there might be DTO like:



@RequiredArgsConstructor
public class TupleDto
@NonNull
private String a,b;



and in your case some sort of PriceListDetailsDto



the repository might be declared like:



public interface TestClassRepository extends CrudRepository<TestClass, Long> 

@Query(value="SELECT new org.example.TupleDto(tc.a, tc.b) FROM TestClass tc")
List<TupleDto> fetchAB();




NOTE: in above that there is used operator new and a full path to the entity constructor.



This way Spring repository knows how to assign selected fields and when making a JSON from this DTO will result having fields with names (names in DTO).



The new operator in JPQL is just calling new in java- So any row data a,b,c can be used to construct Java object with that object's class constructor accepting same parameter amount and types (and in the same order) so liie new MyEntityObject(a,b,c).



NOTE ALSO: in this simple case the original entity could have been used as DTO if it was modified to allow null value in c and adding corresponding constructor. In your case where your tuple is constructed from many tables you need to create a DTO to hold those values.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 12 at 6:03

























answered Nov 10 at 14:41









pirho

3,457101730




3,457101730











  • Thanks for answering, can this approach be used when there is subquery at the column level. Also what is the BaseEntity here ?
    – Manoj Kumar
    Nov 12 at 5:46











  • @ManojKumar I am ont sure what you mean by columnn level. But will add a small update to answer at a moment. The base entity just had the @Id
    – pirho
    Nov 12 at 5:57











  • The fourh column is the subquery
    – Manoj Kumar
    Nov 12 at 6:20










  • @ManojKumar I see. Just add the columns that subquery returns to you DTO & its constructor. In a result set it is still a one or more columns. So if subquery is like select charge_definition_code add yet that charge_definition_code to your DTO and its constructor.
    – pirho
    Nov 12 at 6:24

















  • Thanks for answering, can this approach be used when there is subquery at the column level. Also what is the BaseEntity here ?
    – Manoj Kumar
    Nov 12 at 5:46











  • @ManojKumar I am ont sure what you mean by columnn level. But will add a small update to answer at a moment. The base entity just had the @Id
    – pirho
    Nov 12 at 5:57











  • The fourh column is the subquery
    – Manoj Kumar
    Nov 12 at 6:20










  • @ManojKumar I see. Just add the columns that subquery returns to you DTO & its constructor. In a result set it is still a one or more columns. So if subquery is like select charge_definition_code add yet that charge_definition_code to your DTO and its constructor.
    – pirho
    Nov 12 at 6:24
















Thanks for answering, can this approach be used when there is subquery at the column level. Also what is the BaseEntity here ?
– Manoj Kumar
Nov 12 at 5:46





Thanks for answering, can this approach be used when there is subquery at the column level. Also what is the BaseEntity here ?
– Manoj Kumar
Nov 12 at 5:46













@ManojKumar I am ont sure what you mean by columnn level. But will add a small update to answer at a moment. The base entity just had the @Id
– pirho
Nov 12 at 5:57





@ManojKumar I am ont sure what you mean by columnn level. But will add a small update to answer at a moment. The base entity just had the @Id
– pirho
Nov 12 at 5:57













The fourh column is the subquery
– Manoj Kumar
Nov 12 at 6:20




The fourh column is the subquery
– Manoj Kumar
Nov 12 at 6:20












@ManojKumar I see. Just add the columns that subquery returns to you DTO & its constructor. In a result set it is still a one or more columns. So if subquery is like select charge_definition_code add yet that charge_definition_code to your DTO and its constructor.
– pirho
Nov 12 at 6:24





@ManojKumar I see. Just add the columns that subquery returns to you DTO & its constructor. In a result set it is still a one or more columns. So if subquery is like select charge_definition_code add yet that charge_definition_code to your DTO and its constructor.
– pirho
Nov 12 at 6:24


















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53239376%2fquery-result-in-json-format-key-value-pair-on-using-query-annotation-in-sprin%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

What does pagestruct do in Eviews?

Dutch intervention in Lombok and Karangasem

Channel Islands