2009-09-29 13 views
37

He estado jugando con Scala y me preguntaba si alguien había tenido alguna experiencia con el uso de hibernate y mysql como una tienda persistente para objetos scala. ¿Funciona de la caja o hay mucho que hacer?Hibernate y Scala

Respuesta

22

La mayoría de las veces, Scala + Hibernate funciona bastante bien, con pequeños golpes que podrían superarse fácilmente. Por ejemplo, cuando se trata de colecciones, Hibernate requiere el uso de interfaces java.util. Pero puede importar scala.collection.jcl.Conversions._ si desea hacer clic en la biblioteca más poderosa de Scala.

Es posible que desee comprobar Frank Sommers 'publicar para obtener más información.

+2

_Nota: _ En Scala 2.8 'scala.collection.jcl.Conversions' se renombra como' scala.collection.JavaConversions'. Por lo tanto, debe usar 'import scala.collection.JavaConversions._' en scala 2.8+. Documentos: http://www.scala-lang.org/api/current/scala/collection/JavaConversions$.html. –

+0

Tenga en cuenta que las enumeraciones son una especie de problema con Scala e Hibernate, pero que son posibles de implementar. Aunque sorprendentemente es más fácil en Java. – wmacura

2

No he usado Hibernate con scala directamente, pero estoy usando JPA. Hibernate proporciona una implementación JPA, y la forma de definir las clases persistentes JPA o Hibernate no es muy diferente, entonces creo que usando Hibernate sin la capa JPA es posible

3

Existen problemas. Debido a que algunas características de JPA aprovechan las anotaciones anidadas, p. colecciones, tiene problemas porque Scala aún no admite anotaciones anidadas. Eso desaparecerá cuando salga 2.8.

Consulte Wille Faler’s Blog para obtener más información sobre este tema, más otras incompatibilidades.

3

Tenga en cuenta que Scala 2.8, ahora en RC5 y espera que la liberación en breve, es compatible con anotaciones anidadas. El lanzamiento tiene muchas otras características geniales también.

16

Definitivamente no es mucho trabajo. Un ejemplo simple de hibernación + scala se puede definir en unas pocas decenas de líneas. Scala y Java pueden mezclarse en el mismo proyecto. En particular, la combinación hibernate-scala hace posible combinar el marco JPA y una capa orm muy flexible con la elegancia de las estructuras inmutables y la programación funcional proporcionada por Scala.

La manera más fácil de experimentar con hibernación y scala es mediante el uso de una base de datos hsqldb en memoria a través de hibernate/jpa. Primero, definamos el modelo de dominio. En este caso, una clase scala anotada según el estilo de hibernación, sobre mis amigos.

package nl.busa.jpa 
import javax.persistence._ 

@Entity 
@Table(name = "buddy") 
class Buddy(first: String, last: String) { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    var id: Int = _ 

    var firstName: String = first 
    var lastName: String = last 

    def this() = this (null, null) 

    override def toString = id + " = " + firstName + " " + lastName 
} 

Nota cómo la clase Scala, es mucho más compacta que la clase Java, ya que no es necesario el código estándar típica captador/definidor. Ahora asegurémonos de que los módulos jpa y el modelo de base de datos estén cargados. De acuerdo con la especificación de hibernación, vamos a añadir el archivo de configuración de hibernación conocido: recursos/META-INF/persistence.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" 
     version="2.0"> 
    <persistence-unit name="nl.busa.jpa.HibernateJpaScalaTutorial"> 
     <description> 
     Persistence unit for the JPA tutorial of the Hibernate Getting Started Guide 
     </description> 
     <class>nl.busa.jpa.HibernateJpaScalaTutorial</class> 
     <properties> 
      <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/> 
      <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:mem:JpaScala"/> 
      <property name="hibernate.show_sql" value="false"/> 
      <property name="hibernate.hbm2ddl.auto" value="create"/> 
     </properties> 
    </persistence-unit> 
</persistence> 

Después de definir la configuración de persistencia, vamos a pasar el archivo principal de Scala:

package nl.busa.jpa 

import javax.persistence.EntityManager 
import javax.persistence.EntityManagerFactory 
import javax.persistence.Persistence 

import scala.collection.JavaConversions._ 

object HibernateJpaScalaTutorial  { 

    var entityManagerFactory: EntityManagerFactory = Persistence.createEntityManagerFactory("nl.busa.jpa.HibernateJpaScalaTutorial") 
    var entityManager: EntityManager = entityManagerFactory.createEntityManager() 

    def main(args : Array[String]) { 

    entityManager.getTransaction().begin() 
    entityManager.persist(new Buddy("Natalino", "Busa")) 
    entityManager.persist(new Buddy("Angelina", "Jolie")) 
    entityManager.persist(new Buddy("Kate", "Moss")) 
    entityManager.getTransaction().commit() 

    entityManager.getTransaction().begin(); 
    val allBuddies = entityManager.createQuery("From Buddy", classOf[Buddy]).getResultList.toList 
    entityManager.getTransaction().commit(); 

    allBuddies foreach println 

    entityManager.close(); 

    } 
} 

El código es bastante sencillo.Una vez que el JPA EntityManager se crea de fábrica, el modelo de datos está disponible para su inserción, eliminación, consulta, utilizando los métodos definidos en la documentación de hibernate y jpa.

Este ejemplo se ha configurado con sbt. Después de recuperar los paquetes necesarios, y compilar el código fuente, corriendo el tutorial producirá el siguiente registro:

HibernateJpaScalaTutorial:-:1.0.0> run 
[info] Running nl.busa.jpa.HibernateJpaScalaTutorial 
1 = Natalino Busa 
2 = Angelina Jolie 
3 = Kate Moss 
[success] Total time: 4 s, completed Dec 9, 2012 4:18:00 PM 
3

estoy usando Hibernate con Scala. El verdadero problema que tuve que resolver fue cómo persistir las enumeraciones en hibernación. He puesto mi solución de trabajo en github

Scala-enumeration-hibernate

Básicamente hay que definir propia UserType

abstract class EnumerationAbstractUserType(val et: Enumeration) extends UserType { 
    .... 
    override def nullSafeGet(resultSet: ResultSet, names: Array[String], session: SessionImplementor, owner: Object): Object = { 
    val value = resultSet.getString(names(0)) 
    if (resultSet.wasNull()) null 
    else et.withName(value) 
    } 

    override def nullSafeSet(statement: PreparedStatement, value: Object, index: Int, session: SessionImplementor): Unit = { 
    if (value == null) { 
     statement.setNull(index, Types.VARCHAR) 
    } else { 
     val en = value.toString 
     statement.setString(index, en) 
    } 
}