1

Maven モジュールで構成される Java EE 7 EAR アプリケーションに取り組んでいます。LAN上の別のサーバーにあるOracle 11データベースへのデータベース呼び出しを行います。Ubuntu 12.04 で実行されている Glassfish 4.0.1-b03 にデプロイしています。Oracle から最新の OJDBC6.jar を取得しました。http://docs.oracle.com/cd/E18930_01/html/821-2418/gbxjh.htmlに従って、ojdbc6.jar を に入れましたdomain1/lib/ext

SQLDeveloper を使用して、ほぼ同じクエリでデータベースにクエリを実行すると、10 ミリ秒かかります。JPA/JPQL を介した同じクエリは、構成に応じて 0.5 ~ 3 分かかるため、これをより合理的なものにしようとしています。

クエリは 40 行を返すため、ページネーションは役に立ちません。

返されるデータを監視するために Wireshark を使用していますが、かかる時間はすべてデータベース上にあります。問題は、送信されるクエリにあるはずです。

次のようにロギングをオンにしました。EclipseLinkがDBに送信しているクエリであると思われるものを示しています。

<property name="eclipselink.logging.level" value="FINEST" />
<property name="eclipselink.logging.level.sql" value="FINEST" />

構成 1

persistence.xml には以下が含まれます。

<property name="eclipselink.target-database" value="Oracle"/>

ログのクエリ:

SELECT ALERT_P, CNT, COLOUR, DFROMUIDCNT, FROMUIDCNT, IS_PRIORITYWORD, IS_STOPWORD, N, NIJ, NRTCNT, PJ, RTCCNT, RTCNT, TIME_STAMP, STEM, TWEETS FROM ALL_ALERTS WHERE (TIME_STAMP BETWEEN ? AND ?) ORDER BY TIME_STAMP, STEM

かかった時間 25秒

構成 2

以下を含むように persistence.xml を変更します。

<property name="eclipselink.target-database" value="Oracle11"/>

例外があります:

 org.glassfish.deployment.common.DeploymentException: java.lang.NoSuchFieldError: HINT
                                    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:765)
                                    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getAbstractSession(EntityManagerFactoryDelegate.java:204)
                                    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:304)
                                    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:336)
                                    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:302)
                                    at org.glassfish.persistence.jpa.JPADeployer$2.visitPUD(JPADeployer.java:451)
                                    at org.glassfish.persistence.jpa.JPADeployer$PersistenceUnitDescriptorIterator.iteratePUDs(JPADeployer.java:510)
                                    at org.glassfish.persistence.jpa.JPADeployer.iterateInitializedPUsAtApplicationPrepare(JPADeployer.java:492)
                                    at org.glassfish.persistence.jpa.JPADeployer.event(JPADeployer.java:395)
                                    at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:131)
                                    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:484)
                                    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:219)
                                    at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:491)
                                    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:539)
                                    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:535)
                                    at java.security.AccessController.doPrivileged(Native Method)
                                    at javax.security.auth.Subject.doAs(Subject.java:356)
                                    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:534)
                                    at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:565)
                                    at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:557)
                                    at java.security.AccessController.doPrivileged(Native Method)
                                    at javax.security.auth.Subject.doAs(Subject.java:356)
                                    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:556)
                                    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1464)
                                    at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1300(CommandRunnerImpl.java:109)
                                    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1846)
                                    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1722)
                                    at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:534)
                                    at com.sun.enterprise.v3.admin.AdminAdapter.onMissingResource(AdminAdapter.java:224)
                                    at org.glassfish.grizzly.http.server.StaticHttpHandlerBase.service(StaticHttpHandlerBase.java:189)
                                    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:496)
                                    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:175)
                                    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
                                    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
                                    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:187)
                                    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
                                    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
                                    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
                                    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
                                    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
                                    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
                                    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:837)
                                    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
                                    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
                                    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
                                    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
                                    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
                                    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
                                    at java.lang.Thread.run(Thread.java:722)

http://en.wikibooks.org/wiki/Java_Persistence/Oracleによると、Oracle11 を使用する必要があります。なぜこの例外が発生するのかわかりません。 この問題について何か考えはありますか?

構成 3

eclipselink.target-databasepersistence.xml から削除します。

クエリは次のとおりです。

SELECT ALERT_P, CNT, COLOUR, DFROMUIDCNT, FROMUIDCNT, IS_PRIORITYWORD, IS_STOPWORD, N, NIJ, NRTCNT, PJ, RTCCNT, RTCNT, TIME_STAMP, STEM, TWEETS FROM ALL_ALERTS WHERE (TIME_STAMP BETWEEN ? AND ?) ORDER BY TIME_STAMP, STEM

ああ、それは上記と同じなので、明らかにこれは Oracle に送信されているものではありません。

所要時間: 2.5 分。

したがって、EclipseLink プロパティは役に立ちますが、それを実現できれば、「Oracle11」の値の方が適切に機能する可能性があります。

構成 4

を削除したことを除いて、構成 3と同じORDER BY TIMESTAMP, STEMです。

所要時間: 1.5 分。

構成 5

を削除したことを除いて、構成 1と同じORDER BY TIMESTAMP, STEMです。

かかった時間: 25 秒。

構成 6

を復元し、からにORDER BY移動しました。ojdbc6.jarlib/extlib/

かかった時間: 26 秒。

構成 7

Config 6と同じですが、 を に変更しましたeclipselink.target-databaseOracle11今回のエラーは次のとおりです。

org.glassfish.deployment.common.DeploymentException: java.lang.NoClassDefFoundError: oracle/sql/TIMESTAMP

extOracle固有の拡張機能を取得するには、jarが必要であることをwikiページが正しいことを確認します。

問題は、Oracle に送信されるクエリが最適化されていないことです。

誰でも教えてもらえますか:

  1. 「Oracle11」を使用するときの例外は何ですか(jarが入っているときext/)?
  2. クエリを Oracle 用に最適化する他の方法はありますか?

次に@NamedNativeQuery、SQLDeveloper で使用されているのと同じクエリを使用できるかどうかを確認します。クエリは複雑ではないので、これが JPA の機能を向上させるとは思えません。そのクエリは次のとおりです。

select * from all_alerts t1 WHERE t1.time_stamp between to_date('2013-01-22 16:00:00','YYYY-MM-DD HH24:MI:SS') and to_date('2013-01-22 16:05:00','YYYY-MM-DD HH24:MI:SS') ORDER BY t1.time_stamp, t1.stem;

実際に最初に試みることは、JPQL クエリで送信する日付が同じ形式であることを確認することです。

コメントやフィードバックをお待ちしております。

アップデート

さて、前に追加するのを忘れていた興味深いものがあります。以下@NamedQueryは、予想される時間 (1 つのクエリで 0.086 秒) で実行されます。

        @NamedQuery(name = "AllAlert.findLatestAlerts", query = "SELECT a FROM AllAlert a WHERE a.id.timeStamp in"
            + " (SELECT MAX(a.id.timeStamp) from AllAlert AS a) ORDER BY a.id.stem"),

これは私にはもっと複雑に思えます。

4

0 に答える 0