2013-10-14 35 views
2

我使用SqlResultSetMappingEntity注释(SqlResultSetMapping要求具有Id的实体)来告诉Hibernate如何使用本机查询结果数据填充Foo的实例。如何让Hibernate不为该实体创建表?

非持续的实体:

@SqlResultSetMapping(name = "fooMapping", entities = @EntityResult(entityClass = Foo.class)) 
@Entity 
public class Foo { 
    @Id 
    public Long row_id; 
    public String name; 
} 

本地查询:

String sql = "SELECT id AS row_id, friendlyName AS name FROM SomeTable"; 
Query q = JPA.em().createNativeQuery(sql, "fooMapping"); 
List<Foo> fooList = q.getResultList(); 

的问题是,所谓的“富”表被自动为我创建(!用游戏框架,开发模式) ,但Foo不是一个模型,不应该被持续。

如何指示hibernate不创建此表?

回答

1

使用@ConstructorResult将工作的伟大,一旦它适用于你的持久层。在此之前,有一个Hibernate特定的方法使用org.hibernate.SQLQueryorg.hibernate.transform.ResultTransformer,它不依赖于@SqlResultSetMapping。因为POJO被填充,所以Hibernate找不到@Entity自动变成表格。

非持续POJO:

public class Foo { 
    public Long row_id; 
    public String name; 
} 

使用ResultTransformer:

public static class FooResultTransformer implements ResultTransformer { 

    @Override 
    public List transformList(List list) { return list; } 

    @Override 
    public Object transformTuple(Object[] tuple, String[] aliases) { 
     List<String> aliasList = Arrays.asList(aliases); 
     Foo foo = new Foo(); 
     foo.row_id = ((Number) getValue(tuple, aliasList, "row_id", 0L)) 
      .longValue(); 
     foo.name = (String) getValue(tuple, aliasList, "name", null); 
     return foo; 
    } 

    private static Object getValue(Object[] tuple, List<String> aliases, 
      String field, Object defaultValue) 
    { 
     // unchecked for berevity 
     if (tuple[aliases.indexOf(field)] == null) { 
      return defaultValue; 
     } 
     return tuple[aliases.indexOf(field)]; 
    } 

} 

SQLQuery对原住民:

String sql = "SELECT id AS row_id, friendlyName AS name FROM SomeTable"; 
Session session = JPA.em().unwrap(Session.class); 
SQLQuery q = session.createSQLQuery(sql); 

q.setResultTransformer(new FooResultTransformer()); 
List<Foo> fooList = q.list(); 
1

可惜,这是不容易的......

如果您正在使用@ConstructorResult JPA 2.1的支持(好像有只处于休眠4.3.0.Beta2支持,所以你可能无法使用),可以使用@ConstructorResult如下:

@SqlResultSetMapping(name="fooMapping", 
    classes={ 
    @ConstructorResult(targetClass=Foo.class, columns={ 
     @ColumnResult(name="row_id", type=Integer.class), 
     @ColumnResult(name="name", type=String.class) 
    }) 
    } 
) 

public class Foo { 

    public Long row_id; 
    public String name; 

    public Foo(Long rowId, String name) { 
    ... 
    } 

} 
+1

期待这一点;我将坚持一个适用于JPA 2.0或非beta版Hibernate的解决方案。 –

相关问题