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?
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.
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
La requête Scala N'est pas Hibernate mais peut être intéressante.
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.
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.
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
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)
}
}
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
Jetez un oeil à la version Scala de Play Framework où il y a une adaptation complète de JPA pour Scala.