Подтвердить что ты не робот

Спящий режим и Scala

Я играл с Scala, и мне было интересно, есть ли у кого-нибудь опыт использования hibernate и mysql в качестве постоянного хранилища для объектов Scala? Работает ли это из коробки или есть что делать?

4b9b3361

Ответ 1

В большинстве случаев Scala + Hibernate работает достаточно хорошо, с небольшими ударами, которые можно легко преодолеть. Для exmaple, имея дело с коллекциями, Hibernate требует использования интерфейсов java.util. Но вы можете импортировать scala.collection.jcl.Conversions._, если вы хотите использовать более мощную библиотеку Scala.

Вы можете проверить сообщение Frank Sommers для получения дополнительной информации.

Ответ 2

Это определенно не очень много работы. Пример простой спящего режима + scala может быть определен в нескольких десятках строк. scala, а Java можно смешать в одном проекте. В частности, комбинация спящего режима scala позволяет комбинировать структуру JPA и очень гибкий слой orm с элегантностью неизменяемых структур и функциональным программированием, как предусмотрено scala.

Самый простой способ экспериментировать с hibernate и scala заключается в использовании базы данных hsqldb в памяти через hibernate/jpa. Прежде всего, давайте определим модель домена. В этом случае класс scala аннотируется в соответствии с типом гибернации, о моих друзьях.

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
}

Обратите внимание, что класс scala гораздо более компактен, чем класс java, поскольку нам не нужен типичный шаблон шаблона getter/setter. Теперь давайте удостовериться, что загружены модули jpa и модель базы данных. Согласно спецификации hibernate, добавьте хорошо известный конфигурационный файл спящего режима: resources/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>

После определения конфигурации продолжительности, перейдите в основной файл 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();

  }
}

Код довольно прост. Когда JPA EntityManager создается с помощью factory, модель данных доступна для вставки, удаления, запроса, используя методы, определенные в документации по спящему и jpa.

Этот пример был настроен с использованием sbt. После извлечения необходимых пакетов и компиляции источника, запуск учебника приведет к следующему журналу:

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

Ответ 4

Есть проблемы. Поскольку некоторые функции JPA используют вложенные аннотации, например. коллекции, у вас проблемы, потому что Scala пока не поддерживает вложенные аннотации. Это исчезнет, ​​когда выйдет 2.8.

Подробнее см. Wille Falers Blog, а также другие несовместимости.

Ответ 5

Обратите внимание, что Scala 2.8, теперь в RC5 и ожидается, что он будет выпущен в ближайшее время, поддерживает вложенные аннотации. В релизе также есть много других интересных функций.

Ответ 6

Я использую hibernate с Scala. Реальной проблемой, которую я должен был решить, было то, как перенести перечисления в спящий режим. Я поставил свое рабочее решение на github

Scala-enumeration-hibernate

В основном нужно определить собственный 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)
    }
 }

Ответ 7

Я не использовал Hibernate с scala напрямую, но я использую JPA. Hibernate предоставляет реализацию JPA, и способ определения постоянных классов JPA или Hibernate не сильно отличается, поэтому я думаю, что использование Hibernate без уровня JPA возможно