ElementCollection 在 JSON 响应中返回 Null
ElementCollection returning Null in JSON response
我有以下 elementCollection 声明
在classMyMainClass
@Entity
@Table(name = "MyMainClass")
referencedColumnName="id"))
@NamedQueries({
@NamedQuery(
name = "=findAll",
query = "SELECT s FROM MyMainClass s")})
public class MyMainClass implements Comparable<MyMainClass>, Serializable {
@JsonProperty
@ElementCollection(targetClass=String.class)
@Column
Map<String,String> myMap;
public void setMyMap(Map<String,String> myMap) {
this.myMap = myMap;
}
public Map<String,String> getMyMap() {
return this.myMap;
}
}
这将创建一个 table MyMainClass_myMap
mymainclass_id mymapvalue mymapkey
public List<MyMainClass> findAll(String param) {
Session session = sessionFactory.openSession();
Transaction tx = null;
List<MyMainClass> myMainClass = null;
try {
tx = session.beginTransaction();
String sql = "SELECT * FROM MyMainClass WHERE param = :param ;
SQLQuery query = session.createSQLQuery(sql);
query.setParameter("param", param);
query.addEntity(MyMainClass.class);
myMainClass = query.list();
tx.commit();
}
catch(RuntimeException e) {
if (tx != null) {
tx.rollback();
}
throw e;
}
finally {
session.close();
}
return myMainClass;
}
值 nut JSOn returns 为空。这是为什么?
您定义了一个命名查询来检索 MyMainClass
的所有实例,但在 findAll
中,您使用了 SQL 查询。这是为什么?您的 SQL 查询仅从 MyMainClass
table 检索数据。
您应该做的是使用从 session.getNamedQuery("=findAll")
获得的查询加载实体。为了让实体填充 myMap
,您可以:
- 使用 JPA 注释将元素集合标记为急切获取 (
@ElementCollection(fetch = FetchType.EAGER)
)
- 使用 Hibernate 注释将元素集合标记为急切获取 (
@Fetch(FetchMode.JOIN)
)
- 在命名查询中使用提取连接 (
SELECT s FROM MyMainClass s LEFT JOIN FETCH s.myMap
)
- 在关闭会话之前初始化
myMap
(例如,通过对从查询中检索到的每个实体调用 Hibernate.initialize(entity.getMyMap())
)
选项 #2 和 #3 可能是性能最高的。请注意,只要从 Session
中检索到 MyMainClass
的实例,选项 #1 和 #2 将导致急切地获取 myMap
。如果那是您的意图,那可能就是要走的路。
我有以下 elementCollection 声明
在classMyMainClass
@Entity
@Table(name = "MyMainClass")
referencedColumnName="id"))
@NamedQueries({
@NamedQuery(
name = "=findAll",
query = "SELECT s FROM MyMainClass s")})
public class MyMainClass implements Comparable<MyMainClass>, Serializable {
@JsonProperty
@ElementCollection(targetClass=String.class)
@Column
Map<String,String> myMap;
public void setMyMap(Map<String,String> myMap) {
this.myMap = myMap;
}
public Map<String,String> getMyMap() {
return this.myMap;
}
}
这将创建一个 table MyMainClass_myMap
mymainclass_id mymapvalue mymapkey
public List<MyMainClass> findAll(String param) {
Session session = sessionFactory.openSession();
Transaction tx = null;
List<MyMainClass> myMainClass = null;
try {
tx = session.beginTransaction();
String sql = "SELECT * FROM MyMainClass WHERE param = :param ;
SQLQuery query = session.createSQLQuery(sql);
query.setParameter("param", param);
query.addEntity(MyMainClass.class);
myMainClass = query.list();
tx.commit();
}
catch(RuntimeException e) {
if (tx != null) {
tx.rollback();
}
throw e;
}
finally {
session.close();
}
return myMainClass;
}
值 nut JSOn returns 为空。这是为什么?
您定义了一个命名查询来检索 MyMainClass
的所有实例,但在 findAll
中,您使用了 SQL 查询。这是为什么?您的 SQL 查询仅从 MyMainClass
table 检索数据。
您应该做的是使用从 session.getNamedQuery("=findAll")
获得的查询加载实体。为了让实体填充 myMap
,您可以:
- 使用 JPA 注释将元素集合标记为急切获取 (
@ElementCollection(fetch = FetchType.EAGER)
) - 使用 Hibernate 注释将元素集合标记为急切获取 (
@Fetch(FetchMode.JOIN)
) - 在命名查询中使用提取连接 (
SELECT s FROM MyMainClass s LEFT JOIN FETCH s.myMap
) - 在关闭会话之前初始化
myMap
(例如,通过对从查询中检索到的每个实体调用Hibernate.initialize(entity.getMyMap())
)
选项 #2 和 #3 可能是性能最高的。请注意,只要从 Session
中检索到 MyMainClass
的实例,选项 #1 和 #2 将导致急切地获取 myMap
。如果那是您的意图,那可能就是要走的路。