1

对于使用联接表的更复杂的查询,需要具有别名字段名称的本机 SQL + 重新映射以接收托管实体。

但是,SQL 别名的映射会导致无法找到别名字段的异常。任何人都可以在下面的代码中检测到错误,或者 SQLResultSetMapping 是否损坏?(下面的示例故意简单以便快速检查)

关系型数据库 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")

换句话说,这意味着:没有发生映射 -> 未找到别名字段

在临时查询中宣布映射时也是如此。

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
4

0 回答 0