2013-10-14 27 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的解決方案。 –

相關問題