【问题标题】:Play framework 2.6.x integrating with hibernate orm 4.3.1 mapping errorPlay framework 2.6.x 集成hibernate orm 4.3.1 映射错误
【发布时间】:2017-12-25 01:22:26
【问题描述】:

我正在尝试将我的 java play 应用程序与 hibernate orm 集成,这是我的项目结构。

如您所见,我已将我的 pojos 放在一个名为 models 的包中,并将 hibernate.cfg.xml 放在 conf 中。

hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/db_name</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">password</property>
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <property name="hibernate.enable_lazy_load_no_trans">true</property>

        <mapping resource="models/Coating.hbm.xml"/>
        <mapping resource="models/Fitting.hbm.xml"/>
        <mapping resource="models/Product.hbm.xml"/>
        <mapping resource="models/ProductHasCoating.hbm.xml"/>
        <mapping resource="models/ProductHasFitting.hbm.xml"/>
        <mapping resource="models/ProductHasSize.hbm.xml"/>
        <mapping resource="models/Size.hbm.xml"/>

    </session-factory>
</hibernate-configuration>

HibernateUtil 类:(在services 内)

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

public class HibernateUtil {

    private static final SessionFactory sessionFactory;

    static {
        try {
            // Create the SessionFactory from standard (hibernate.cfg.xml)
            // config file.
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            // Log the exception.
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

控制器类

public class LoginController extends Controller {

    public Result login() throws SQLException {
        Session s = HibernateUtil.getSessionFactory().openSession();
        Criteria c = s.createCriteria(Coating.class);
        c.add(Restrictions.eq("code", "CO3444"));
        Coating co = (Coating) c.uniqueResult();
        String title = co.getTitle();
        s.close();
        return ok(views.html.login_page.login.render(title));
    }
}

对我来说一切都很好,一旦我编译并运行应用程序,它会终止应用程序服务器并出现以下错误。

Initial SessionFactory creation failed.org.hibernate.InvalidMappingException: Could not parse mapping document from resource models/Coating.hbm.xml
Uncaught error from thread [play-dev-mode-akka.actor.default-dispatcher-4]: null, shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled for for ActorSystem[play-dev-mode]
java.lang.ExceptionInInitializerError
        at services.HibernateUtil.<clinit>(HibernateUtil.java:18)
        at controllers.LoginController.login(LoginController.java:15)
        at router.Routes$$anonfun$routes$1.$anonfun$applyOrElse$2(Routes.scala:164)
        at play.core.routing.HandlerInvokerFactory$$anon$3.resultCall(HandlerInvoker.scala:134)
        at play.core.routing.HandlerInvokerFactory$$anon$3.resultCall(HandlerInvoker.scala:133)
        at play.core.routing.HandlerInvokerFactory$JavaActionInvokerFactory$$anon$8$$anon$2$$anon$1.invocation(HandlerInvoker.scala:108)
        at play.core.j.JavaAction$$anon$1.call(JavaAction.scala:82)
        at play.http.DefaultActionCreator$1.call(DefaultActionCreator.java:31)
        at play.core.j.JavaAction.$anonfun$apply$8(JavaAction.scala:132)
        at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:653)
        at scala.util.Success.$anonfun$map$1(Try.scala:251)
        at scala.util.Success.map(Try.scala:209)
        at scala.concurrent.Future.$anonfun$map$1(Future.scala:287)
        at scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:29)
        at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:29)
        at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
        at play.core.j.HttpExecutionContext$$anon$2.run(HttpExecutionContext.scala:56)
        at play.api.libs.streams.Execution$trampoline$.execute(Execution.scala:70)
        at play.core.j.HttpExecutionContext.execute(HttpExecutionContext.scala:48)
        at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:68)
        at scala.concurrent.impl.Promise$KeptPromise$Kept.onComplete(Promise.scala:368)
        at scala.concurrent.impl.Promise$KeptPromise$Kept.onComplete$(Promise.scala:367)
        at scala.concurrent.impl.Promise$KeptPromise$Successful.onComplete(Promise.scala:375)
        at scala.concurrent.impl.Promise.transform(Promise.scala:29)
        at scala.concurrent.impl.Promise.transform$(Promise.scala:27)
        at scala.concurrent.impl.Promise$KeptPromise$Successful.transform(Promise.scala:375)
        at scala.concurrent.Future.map(Future.scala:287)
        at scala.concurrent.Future.map$(Future.scala:287)
        at scala.concurrent.impl.Promise$KeptPromise$Successful.map(Promise.scala:375)
        at scala.concurrent.Future$.apply(Future.scala:653)
        at play.core.j.JavaAction.apply(JavaAction.scala:132)
        at play.api.mvc.Action.$anonfun$apply$2(Action.scala:96)
        at play.api.libs.streams.StrictAccumulator.$anonfun$mapFuture$4(Accumulator.scala:174)
        at scala.util.Try$.apply(Try.scala:209)
        at play.api.libs.streams.StrictAccumulator.$anonfun$mapFuture$3(Accumulator.scala:174)
        at scala.Function1.$anonfun$andThen$1(Function1.scala:52)
        at scala.Function1.$anonfun$andThen$1(Function1.scala:52)
        at play.api.libs.streams.StrictAccumulator$$anon$1.apply(Accumulator.scala:218)
        at play.api.libs.streams.StrictAccumulator$$anon$1.apply(Accumulator.scala:217)
        at java.util.function.Function.lambda$andThen$1(Function.java:88)
        at java.util.function.Function.lambda$andThen$1(Function.java:88)
        at play.libs.streams.Accumulator$StrictAccumulator$1.apply(Accumulator.java:403)
        at play.libs.streams.Accumulator$StrictAccumulator$1.apply(Accumulator.java:400)
        at scala.Function1.$anonfun$andThen$1(Function1.scala:52)
        at scala.Function1.$anonfun$andThen$1(Function1.scala:52)
        at scala.Function1.$anonfun$andThen$1(Function1.scala:52)
        at play.api.libs.streams.StrictAccumulator.run(Accumulator.scala:207)
        at play.core.server.AkkaHttpServer.executeAction(AkkaHttpServer.scala:298)
        at play.core.server.AkkaHttpServer.executeHandler(AkkaHttpServer.scala:255)
        at play.core.server.AkkaHttpServer.handleRequest(AkkaHttpServer.scala:201)
        at play.core.server.AkkaHttpServer.$anonfun$createServerBinding$1(AkkaHttpServer.scala:107)
        at akka.stream.impl.fusing.MapAsync$$anon$24.onPush(Ops.scala:1191)
        at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:512)
        at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:475)
        at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:371)
        at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:584)
        at akka.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:468)
        at akka.stream.impl.fusing.GraphInterpreterShell.processEvent(ActorGraphInterpreter.scala:559)
        at akka.stream.impl.fusing.ActorGraphInterpreter.akka$stream$impl$fusing$ActorGraphInterpreter$$processEvent(ActorGraphInterpreter.scala:741)
        at akka.stream.impl.fusing.ActorGraphInterpreter$$anonfun$receive$1.applyOrElse(ActorGraphInterpreter.scala:756)
        at akka.actor.Actor.aroundReceive(Actor.scala:517)
        at akka.actor.Actor.aroundReceive$(Actor.scala:515)
        at akka.stream.impl.fusing.ActorGraphInterpreter.aroundReceive(ActorGraphInterpreter.scala:666)
        at akka.actor.ActorCell.receiveMessage(ActorCell.scala:527)
        at akka.actor.ActorCell.invoke(ActorCell.scala:496)
        at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:257)
        at akka.dispatch.Mailbox.run(Mailbox.scala:224)
        at akka.dispatch.Mailbox.exec(Mailbox.scala:234)
        at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
        at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
        at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
        at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: org.hibernate.InvalidMappingException: Could not parse mapping document from resource models/Coating.hbm.xml
        at org.hibernate.cfg.Configuration$MetadataSourceQueue.processHbmXml(Configuration.java:3764)
        at org.hibernate.cfg.Configuration$MetadataSourceQueue.processHbmXmlQueue(Configuration.java:3753)
        at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3741)
        at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1410)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928)
        at services.HibernateUtil.<clinit>(HibernateUtil.java:14)
        ... 71 more
Caused by: org.hibernate.MappingException: class models.Coating not found while looking for property: id
        at org.hibernate.internal.util.ReflectHelper.reflectedPropertyClass(ReflectHelper.java:233)
        at org.hibernate.mapping.SimpleValue.setTypeUsingReflection(SimpleValue.java:362)
        at org.hibernate.cfg.HbmBinder.bindSimpleId(HbmBinder.java:453)
        at org.hibernate.cfg.HbmBinder.bindRootPersistentClassCommonValues(HbmBinder.java:386)
        at org.hibernate.cfg.HbmBinder.bindRootClass(HbmBinder.java:326)
        at org.hibernate.cfg.HbmBinder.bindRoot(HbmBinder.java:177)
        at org.hibernate.cfg.Configuration$MetadataSourceQueue.processHbmXml(Configuration.java:3761)
        ... 77 more
Caused by: java.lang.ClassNotFoundException: models.Coating
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:264)
        at org.hibernate.internal.util.ReflectHelper.classForName(ReflectHelper.java:193)
        at org.hibernate.internal.util.ReflectHelper.reflectedPropertyClass(ReflectHelper.java:229)
        ... 83 more

更新

但是一旦我从 hibernate.cfg.xml 中删除所有映射并将 LoginController 代码更改为以下:

        Session s = HibernateUtil.getSessionFactory().openSession();
        Connection c = s.getSessionFactory().getSessionFactoryOptions().getServiceRegistry()
                .getService(ConnectionProvider.class).getConnection();

        //Criteria c = s.createCriteria(Coating.class);
        //c.add(Restrictions.eq("code", "CO3444"));
        //Coating co = (Coating) c.uniqueResult();
        //String title = co.getTitle();
        //s.close();
        String title = c.getMetaData().getDatabaseProductName();
        return ok(views.html.login_page.login.render(title));

应用程序在浏览器中启动并正常运行,输出为MySQL 这意味着没有任何休眠配置错误,并且 HibernateUtil 类也没有任何错误。

任何帮助都将不胜感激。谢谢。

【问题讨论】:

    标签: java hibernate playframework orm


    【解决方案1】:

    在这种情况下,play-framework 不会在模型包中查找 xml 映射。所以我必须将它们与hibernate.cfg.xml 一起放在conf 包中。下图显示了项目结构的样子:

    然后不要忘记添加

    Thread.currentThread().setContextClassLoader(OneOfYourModelClass.class.getClassLoader());
    

    在构建会话工厂之前,在 HibernateUtil 类中添加一行。

    ...
     static {
            try {
                Thread.currentThread().setContextClassLoader(SomeClass.class.getClassLoader());
                sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
            } catch (Throwable ex) {
    ...
    

    因此可以为一个实体设置ClassLoader 的上下文,并且其他实体也可以正确加载。

    【讨论】: