具有别名字段名称的本机SQL +用于接收管理实体的重新映射对于具有连接表的更复杂查询是必需的。
但是,SQL别名的映射会导致无法找到别名字段的异常。任何人都可以在下面的代码中检测到错误,或者SQLResultSetMapping是否已损坏? (以下示例有意简单,以便快速检查)
RDBMS H2,DDL
create table A(
ID INTEGER DEFAULT NOT NULL AUTO_INCREMENT PRIMARY KEY,
VAL VARCHAR(10)
);
insert into A (val) values ('val1');
insert into A (val) values ('val2');
Java类
@Entity
@NamedNativeQuery(name = "queryall",
query="select ID as AID, val from A",
resultSetMapping = "mapping")
@SqlResultSetMapping(name = "mapping",
entities = @EntityResult(
entityClass = A.class,
fields = {@FieldResult(name = "ID", column = "AID")})
)
public class A implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Integer id;
@Column(name = "VAL")
private String val;
public A() {
}
public A(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
@Override
public String toString() {
return "entities.A[ id=" + id +", val="+val+ " ]";
}
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory =
Persistence.createEntityManagerFactory("JavaApplication6PU");
EntityManager em = entityManagerFactory.createEntityManager();
Query sqlQuery = em.createNamedQuery("queryall");
List list = sqlQuery.getResultList();
for (Iterator<A> iterator = list.iterator(); iterator.hasNext();) {
a = iterator.next();
System.out.println(String.format("entity %s, managed: %s", a, em.contains(a)));
}
}
}
执行因异常而停止:
[EL Warning]: 2018-01-12 21:45:42.748--UnitOfWork(1823014131)--Exception
[EclipseLink-6044] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd):
org.eclipse.persistence.exceptions.QueryException
Exception Description: The primary key read from the row [DatabaseRecord(
A.ID => null
A.VAL => val1)] during the execution of the query was detected to be null.
Primary keys must not contain null.
Query: ResultSetMappingQuery(name="queryall" referenceClass=A sql="select ID as AID, val from A")
换句话说,这意味着:没有发生映射 - &gt;找不到别名字段
在特殊查询中宣布映射时相同。
Query sqlQuery = em.createNativeQuery("select ID as AID, val from A","mapping");
如果使用resultClass而不是resultSetMapping且不存在SQL别名,则输出应该是原样。 (这证明没有拼写错误的字段或任何其他错误)
@NamedNativeQuery(name = "queryall",
query="select ID, val from A",
resultClass = A.class)
输出:
entity entities.A[ id=1, val=val1 ], managed: true
entity entities.A[ id=2, val=val2 ], managed: true