0

I have a Java Class named User with

@Column(name = "id")
private Long id;
@NotNull
@Column(name = "NAME")
private String name;

I am trying to get some details in a list and convert it into JSOn like so:

Session session = this.sessionFactory.getCurrentSession();
String queryString="select id,name from User where unit=:name";
Query query= sessionFactory.getCurrentSession().createQuery(queryString);
query.setParameter("name", name);
List<User> users= (List<User>) query.list();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
Map<String, List<User>> wrap = new HashMap<>();
wrap.put("users", users);  // wrap user list in a map
String json = gson.toJson(wrap);

This produces a JSON

{
 "users": [
 [
  1,
  "Room"
],
[
  2,
  "Regi"
 ],
 ]
}

How do I change it so that I get a JSON like

{
 "users": [
 [
   "id":1,
   "name":"Rovom"
 ],
 [
   "id":2,
   "name":"Regi"
 ],
]
}

Edit I realized it is the query that is causing the issue. If i use

String queryString="from User where unit=:name";

It gives the correct format. How do I fix this?

4
  • 1
    Are you forced to use gson? I was just thinking that jackson for instance would probably do it right directly Commented Jun 19, 2020 at 10:37
  • 1
    oh - and your "expected result" still is not right - should be "users": [ {"id": 1, "name": Rovom"}, { ... as it's a list ob objects, not a list of arrays Commented Jun 19, 2020 at 10:39
  • @Jan no I am not forced to use Gson. Can you post the solution using Jackson. Commented Jun 19, 2020 at 10:46
  • Issue is not reproducible. Can you please update the question with complete User class or even better a minimal reproducible example Commented Jun 19, 2020 at 11:25

3 Answers 3

1

Whith jackson, it'll look like this:

   String json = new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueToString(wrap);

You'd want jackson-core and jackson-databind for this at least.

Full example using Jackson:

public static class User {
    private Long id;
    private String name;

    public User(long i, String n) {
        id = i;
        name = n;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

public static void main(String... args) {
    try {
        Map<String,Object> map = new HashMap<>();
        map.put("users",  Arrays.asList(new User(1, "Stack"), new User(2, "Overflow")));
        System.out.println(new ObjectMapper().writerWithDefaultPrettyPrinter()
                .writeValueAsString(map));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

produced this output:

{
  "users" : [ {
    "id" : 1,
    "name" : "Stack"
  }, {
    "id" : 2,
    "name" : "Overflow"
  } ]
}
Sign up to request clarification or add additional context in comments.

3 Comments

Still getting the same output. Is it possible there is a binding issue between the object and the query?
can you share full object code for User then please?
I have edited the question. It is related to the query. Please check. Thanks
1

Hm, looks like type erasure at runtime.

Your List<User> is with the first query actually a List<Object[]> as which it got serialized. Would you try to access an User-object out of the list, you'd get a runtime error, I suppose.

See hibernate documentation:

Return the query results as a List. If the query contains multiple results pre row, the results are returned in an instance of Object[].

EDIT

to get a list of Users with only the two fields filled, create the apropriate constructur and use a query like

select new package.path.to.class.User(id,name) from User where unit=:name"

5 Comments

You might be on to something here. The getName() etc gives errors as well
@MontySwanson actually, i'm quite sure ;-)
So whats the fix?
The right query is the fix. With the original query List<User> users= (List<User>) query.list(); is clearly wrong, only the compiler can't detect it.If yout Issue is, that User has many more fields you don't want in the JSON, you have to tell us...
Yes it has other fields. Name, ID, department, address etc. Some of them are references to other classes
0

As mentioned by user @Turo this is because of type erasure at runtime.

To fix this, the query has to be changed to

String queryString="select id,name from User where unit=:name";
Query query= sessionFactory.getCurrentSession().createSQLQuery(queryString).addScalar("name", new StringType()).addScalar("id", new IntType()).setResultTransformer(Transformers.aliasToBean(User.class));

query.setParameter("name", name);

the addScalar() will map the values to the User objects and this gives the required result.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.