2010-05-28 9 views
5

Estoy empezando a entender con JPA en una simple aplicación web de Java que se ejecuta en Glassfish 3 (el proveedor de persistencia es EclipseLink). Hasta el momento, me está gustando (los errores en la interacción netbeans/glassfish aparte) pero hay algo que quiero poder hacer y no estoy seguro de cómo hacerlo.JPA - ¿Establecer propiedad de clase de entidad desde la columna calculada?

Tengo una clase de entidad (Artículo) que está mapeada en una tabla de base de datos (artículo). Estoy tratando de hacer una consulta en la base de datos que devuelve una columna calculada, pero no puedo averiguar cómo configurar una propiedad de la clase Artículo para que la propiedad se llene por el valor de la columna cuando llamo a la consulta.

Si realizo una consulta normal de "selección de id, título, cuerpo del artículo", obtengo una lista de objetos de artículo fina, con las propiedades id, title y body completadas. Esto funciona bien

Sin embargo, si hago el siguiente:

Query q = em.createNativeQuery("select id,title,shorttitle,datestamp,body,true as published, ts_headline(body,q,'ShortWord=0') as headline, type from articles,to_tsquery('english',?) as q where idxfti @@ q order by ts_rank(idxfti,q) desc",Article.class); 

(se trata de una búsqueda de texto completo usando tsearch2 en Postgres - es una función-db específica, por lo que estoy usando un NativeQuery)

Usted puedo ver que estoy buscando una columna calculada, llamada título. ¿Cómo agrego una propiedad de título a mi clase de artículo para que se rellene con esta consulta?

Hasta ahora, he intentado configurarlo para que sea @Transient, pero eso acaba siendo nulo todo el tiempo.

Respuesta

7

probablemente no hay buenas maneras de hacerlo, solamente de forma manual:

Object[] r = (Object[]) em.createNativeQuery(
    "select id,title,shorttitle,datestamp,body,true as published, ts_headline(body,q,'ShortWord=0') as headline, type from articles,to_tsquery('english',?) as q where idxfti @@ q order by ts_rank(idxfti,q) desc","ArticleWithHeadline") 
    .setParameter(...).getSingleResult(); 

Article a = (Article) r[0]; 
a.setHeadline((String) r[1]); 

-

@Entity 
@SqlResultSetMapping(
    name = "ArticleWithHeadline", 
    entities = @EntityResult(entityClass = Article.class), 
    columns = @ColumnResult(name = "HEADLINE")) 
public class Article { 
    @Transient 
    private String headline; 
    ... 
} 
2

yo sepa, la APP no ofrece soporte estandarizado para atributos calculados. Con Hibernate, uno usaría un Formula pero EclipseLink no tiene un equivalente directo. James Sutherland hizo algunas sugerencias en Re: Virtual columns (@Formula of Hibernate) sin embargo:

No hay un equivalente directo (por favor registro de una mejora), pero dependiendo de lo que quiere hacer, hay maneras de lograr lo mismo.

EclipseLink define un TransformationMapping que puede asignar un valor calculado a partir de múltiples campo valores, o acceder a la base de datos.

Puede anular el SQL para cualquier operación CRUD para una clase utilizando su DescriptorQueryManager del descriptor .

Se podría definir una vista en su base de datos que realiza la función y el mapa de su entidad a la vista lugar de la tabla.

También puede realizar traducciones menores utilizando convertidores o propiedad obtener/establecer métodos.

también echar un vistazo a la enhancement request que tiene una solución con un DescriptorEventListener en los comentarios.

Todo esto es JPA no estándar, por supuesto.

Cuestiones relacionadas