Hibernate et Scala [fermé]

J'ai joué avec Scala et je me demandais si quelqu'un avait eu une expérience avec l'utilisation de hibernate et mysql comme magasin persistant pour les objets scala? Cela fonctionne hors de la boîte ou il y a beaucoup de choses à faire?

37
demandé sur Charles 2009-09-30 00:36:58

8 réponses

La plupart du temps, Scala + Hibernate fonctionne assez bien, avec des bosses mineures qui pourraient être surmontées facilement. Pour exmaple, Lorsqu'il s'agit de collections, Hibernate nécessite l'utilisation de java.interfaces util. Mais vous pouvez importer scala.collection.jcl.Conversion._ si vous voulez appuyer sur la bibliothèque plus puissante de Scala.

Vous pouvez consulter Frank Sommers' post pour plus d'informations.

22
répondu shaolang 2009-09-30 03:55:59

Ce n'est certainement pas beaucoup de travail. Un exemple simple hibernate + scala peut être défini en quelques dizaines de lignes. Scala et Java peuvent être mélangés dans le même projet. En particulier, la combinaison hibernate-scala permet de combiner le framework JPA, et une couche orm très flexible avec l'élégance des structures immuables et de la programmation fonctionnelle fournie par scala.

La façon la plus simple d'expérimenter hibernate et scala est d'utiliser une base de données HSQLDB en mémoire via hibernate / jpa. Tout d'abord, définissons le modèle de domaine. Dans ce cas, une classe scala annotée selon le style hibernate, à propos de mes copains.

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
}

Notez que la classe scala est beaucoup plus compacte que la classe java, car nous n'avons pas besoin du code standard getter/setter. Maintenant, nous allons nous assurer, que les modules jpa et le modèle de base de données est chargé. Selon la spécification hibernate, ajoutons le fichier de configuration hibernate bien connu: ressources / META-INF / persistance.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>

Après avoir défini la configuration de persistance, passons au fichier scala principal:

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();

  }
}

Le code est assez simple. Une fois que le JPA EntityManager est créé via l'usine, le modèle de données est disponible pour l'insertion, la suppression, la requête, en utilisant les méthodes définies dans la documentation de hibernate et jpa.

Cet exemple a été configuré à l'aide de sbt. Après avoir récupéré les paquets nécessaires et compilé la source, exécutez le tutoriel produira le journal suivant:

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
16
répondu natbusa 2012-12-09 15:47:41
8
répondu Phil 2009-10-09 01:44:21

Il y a des problèmes. Comme certaines fonctionnalités de JPA exploitent les annotations imbriquées, par exemple les collections, vous êtes en difficulté car Scala ne prend pas encore en charge les annotations imbriquées. Ça disparaîtra quand 2.8 sortira.

Voir Le Blog de Wille Faler pour plus d'informations sur ce sujet et d'autres incompatibilités.

3
répondu andyczerwonka 2009-10-08 21:24:52

Notez que Scala 2.8, maintenant dans RC5 et devrait sortir sous peu, prend en charge les annotations imbriquées. La presse a beaucoup d'autres fonctionnalités intéressantes ainsi.

3
répondu user369563 2010-06-17 16:35:02

J'utilise hibernate avec Scala. Le vrai problème que j'ai dû résoudre était de savoir comment persister les énumérations en hibernate. J'ai mis ma solution de travail sur github

Scala-énumération-hibernate

Fondamentalement, il faut définir son propre 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)
    }
 }
3
répondu Marek Zebrowski 2013-10-20 13:45:40

Je n'ai pas utilisé Hibernate directement avec scala, mais j'utilise JPA. Hibernate fournit une implémentation JPA, et la façon dont vous définissez les classes persistantes JPA ou Hibernate n'est pas très différente, donc je pense que L'utilisation D'Hibernate sans la couche JPA est possible

2
répondu robmv 2009-09-29 21:55:45

Jetez un oeil à la version Scala de Play Framework où il y a une adaptation complète de JPA pour Scala.

0
répondu takacsot 2012-02-07 15:40:45