2012-05-25 12 views
6

Intentando usar hibernate/jpa con scala. Se encuentra con un problema interesante.

Esta es la definición de mi entidad.

@Entity 
class Product(n: String, d: Double) extends EntityBase { 

    def this() = this("", 0) 
    def this(n: String) = this(n, 0) 

    var name: String = n 
    var price: Double = d 

    @ManyToOne 
    @JoinColumn(name="orderId") 
    var order: Order = _ 

    override def toString = "Product: " + id + " " + name 
} 

Cuando corro consulta de hibernación que estoy recibiendo la siguiente excepción:

[SQLGrammarException: ERROR: column this_.bitmap$init$0 does not exist Position: 29] 

Obviamente JPA por defecto crea mapeo para Scala campo de mapa de bits autogenerado $ init 0 $. No sé qué causa Scala para generarlo. Pero independientemente de que haya alguna solución para decirle a jpa que lo ignore? ¿O de alguna manera eliminarlo del mapeo de hibernación? O tal vez algo más ..

+0

Tengo absolutamente el mismo problema. Pero parece que solo hay dos personas que lo cumplen. –

Respuesta

0

no sé donde ese campo autogenerado está viniendo, pero se puede tratar de optimizar su clase para tener menos campos:

@Entity 
class Product(var name: String = "", var price: Double = 0) extends EntityBase { 

    @ManyToOne 
    @JoinColumn(name="orderId") 
    var order: Order = _ 

    override def toString = "Product: " + id + " " + name 
} 
+0

parece más limpio. Gracias. – serg

0

encontrado un par de cosas interesantes acerca este problema.

que tienen esta clase Model en mi solicitud:

@Entity 
@Table(name="users") 
class User extends Model{ 
    @Id 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="users_id_seq") 
    @Column(name="id", updatable=false, nullable=false) 
    val id:Long = 0L 

    @BeanProperty var name:String = _ 
    @BeanProperty var email:String = _ 

}

Esta clase se compila a una clase Java llamada User, que a su vez se define así:

@Entity 
@Table(name="users") 
@ScalaSignature(bytes=long array of bytes) 
public class User extends Model 
    implements ScalaObject, EntityBean 
{ 

    @Id 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="users_id_seq") 
    @Column(name="id", updatable=false, nullable=false) 
    private final long id; 
    private String name; 
    private String email; 
    private volatile int bitmap$init$0; 
    private static String _EBEAN_MARKER = "models.User"; 

    ... 

    public long id() 
    { 
    if ((_ebean_get_bitmap$init$0() & 0x1) != 0) 
    { 
     _ebean_get_id(); return _ebean_get_id(); 
    } 
    throw new 
     UninitializedFieldError("Uninitialized field: User.scala: 17".toString()); 
    } 

    public String name() 
    { 
    if ((_ebean_get_bitmap$init$0() & 0x2) != 0) 
    { 
    _ebean_get_name(); return _ebean_get_name(); 
    } throw new 
      UninitializedFieldError("Uninitialized field: User.scala: 19".toString()); 
    } 

    public void name_$eq(String paramString) { 
    _ebean_set_name(paramString); 
     _ebean_set_bitmap$init$0(_ebean_get_bitmap$init$0() | 0x2); 
    } 

    .... 

El bitmap$init$0 en realidad proviene de una mejora de clase, y pensé que el responsable era el Ebean biblioteca, que estoy usando actualmente. Pero después de leer tu publicación, investigué si JPA estaba realizando algún tipo de mejora de bytecode en este objeto. Para verificar esto, creé un proyecto de copia, pero en Java. El código generado para la clase User pasa a tener ningún campo bitmap$init$0, de la siguiente manera:

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.Table; 

@Entity 
@Table(name="users") 
public class User 
{ 

    @Id 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="users_id_seq") 
    @Column(name="id", updatable=false, nullable=false) 
    private Long id; 
    private String name; 
    private String email; 

public void setId(Long id) 
{ 
    this.id = id; 
} 

public Long getId() { 
    return this.id; 
} 

public String getName() { 
    return this.name; 
} 
public void setName(String name) { 
    this.name = name; 
} 
public String getEmail() { 
    return this.email; 
} 
public void setEmail(String email) { 
    this.email = email; 
    } 
} 

Todo este tipo de problemas me llevó a este post y yo, ciertamente, de acuerdo. Parece que la integración de JPA a Scala Ebean/Hibernate es una especie de dolor real. Todavía no entendí si este campo bitmap$ini$0 está inyectado en el bytecode de clase por Ebean u otra cosa.

Parece que se puede tratar de evitar este tipo de comportamiento mediante la asociación de una anotación (@Transitent) para el código de bytes de Java generado, mediante la compilación del código java primero para luego a Scala, algo similar a lo que es described here. ¡Pero realmente no creo que eso sea realmente digno!