moqui / moqui-framework

Use Moqui Framework to build enterprise applications based on Java. It includes tools for databases (relational, graph, document), local and web services, web and other UI with screens and forms, security, file/resource access, scripts, templates, l10n, caching, logging, search, rules, workflow, multi-instance, and integration.
http://www.moqui.org
Other
281 stars 201 forks source link

Oracle & Moqui Errros #327

Open amirmf opened 6 years ago

amirmf commented 6 years ago

i'm using oracle 11g with ojdbc8 driver and moqui latest version (master branch)

this is my conf:

  <database name="oracle" join-style="ansi" default-isolation-level="ReadCommitted"
                  default-test-query="SELECT 1 FROM DUAL" default-jdbc-driver="oracle.jdbc.driver.OracleDriver"
                  default-startup-add-missing="true" default-runtime-add-missing="false"
                  default-xa-ds-class="oracle.jdbc.xa.client.OracleXADataSource" never-nulls="true">
            <database-type type="id" sql-type="VARCHAR2(40)"/>
            <database-type type="id-long" sql-type="VARCHAR2(255)"/>

            <database-type type="number-integer" sql-type="NUMBER(24,0)"/>
            <database-type type="number-decimal" sql-type="NUMBER(30,6)"/>
            <database-type type="number-float" sql-type="NUMBER(36,12)"/>

            <database-type type="currency-amount" sql-type="NUMBER(26,2)"/>
            <database-type type="currency-precise" sql-type="NUMBER(27,3)"/>

            <database-type type="text-short" sql-type="VARCHAR2(47)"/>
            <database-type type="text-medium" sql-type="VARCHAR2(255)"/>
            <database-type type="text-long" sql-type="VARCHAR2(4000)"/>

            <inline-jdbc><xa-properties user="${entity_ds_user}" password="${entity_ds_password}"
                    URL="jdbc:oracle:thin:@${entity_ds_host}:${entity_ds_port?:'1521'}:${entity_ds_database}"/></inline-jdbc>
        </database>

AND

   <datasource group-name="transactional" database-conf-name="oracle" schema-name="MOQUI">
            <inline-jdbc jdbc-uri="jdbc:oracle:thin:@127.0.0.1:1521:moqui" jdbc-username="moqui" jdbc-password="moqui"/>
        </datasource>

1- when trying to open any pages in tools & system menu i got this error of list query

12:19:51.872  WARN 7015-exec-95                  o.m.i.s.ScreenUrlInfo Tried to get URL for screen path [favicon.ico] that does not exist under component://webroot/screen/webroot.xml, returning hash
12:19:51.884  WARN 7015-exec-95         o.moqui.i.e.EntityQueryBuilder Error in JDBC query for SQL SELECT ORIGINAL, LOCALE, LOCALIZED, LAST_UPDATED_STAMP FROM LOCALIZED_MESSAGE ORDER BY UPPER(ORIGINAL) ASC, LOCALE ASC OFFSET 0 ROWS FETCH FIRST 50 ROWS ONLY
12:19:51.884 ERROR 7015-exec-95                      o.m.i.a.XmlAction Error running groovy script (Error finding list of LocalizedMessage by null [42000]):
1 : import static org.moqui.util.ObjectUtilities.*
2 : import static org.moqui.util.CollectionUtilities.*
3 : import static org.moqui.util.StringUtilities.*
4 : import java.sql.Timestamp
5 : // these are in the context by default: ExecutionContext ec, Map<String, Object> context, Map<String, Object> result
6 :     localizedMessageList_xafind = ec.entity.find("moqui.basic.LocalizedMessage").offset(0).limit(50)
7 :
8 :         if (true) {
9 :         Map efSfiDefParms = null
10 :         localizedMessageList_xafind.searchFormMap(ec.context, efSfiDefParms, "", "^original,locale", true)
11 :     }
12 :         localizedMessageList = localizedMessageList_xafind.list()
13 :             if (localizedMessageList_xafind.getLimit() == null) {
14 :                 localizedMessageListCount = localizedMessageList.size()
15 :                 localizedMessageListPageIndex = localizedMessageList.pageIndex
16 :                 localizedMessageListPageSize = localizedMessageListCount > 20 ? localizedMessageListCount : 20
17 :             } else {
18 :                 localizedMessageListCount = localizedMessageList_xafind.count()
19 :                 localizedMessageListPageIndex = localizedMessageList_xafind.pageIndex
20 :                 localizedMessageListPageSize = localizedMessageList_xafind.pageSize
21 :             }
22 :         localizedMessageListPageMaxIndex = ((BigDecimal) (localizedMessageListCount - 1)).divide(localizedMessageListPageSize ?: (localizedMessageListCount - 1), 0, BigDecimal.ROUND_DOWN) as int
23 :         localizedMessageListPageRangeLow = localizedMessageListPageIndex * localizedMessageListPageSize + 1
24 :         localizedMessageListPageRangeHigh = (localizedMessageListPageIndex * localizedMessageListPageSize) + localizedMessageListPageSize
25 :         if (localizedMessageListPageRangeHigh > localizedMessageListCount) localizedMessageListPageRangeHigh = localizedMessageListCount
26 : // make sure the last statement is not considered the return value
27 : return;

12:19:51.884 ERROR 7015-exec-95               o.m.i.s.ScreenRenderImpl Error rendering screen [component://tools/screen/System/Localization/Messages.xml]
org.moqui.impl.entity.EntitySqlException: Error finding list of LocalizedMessage by null [42000]
        at org.moqui.impl.entity.EntityFindBase.listInternal(EntityFindBase.groovy:1083) ~[moqui-framework-2.1.1-rc2.jar:2.1.1-rc2]
        at org.moqui.impl.entity.EntityFindBase.list(EntityFindBase.groovy:946) ~[moqui-framework-2.1.1-rc2.jar:2.1.1-rc2]
        at component___tools_screen_System_Localization_Messages_xml_screen_actions.run(component___tools_screen_System_Localization_Messages_xml_screen_actions:12) ~[script:?]
        at org.moqui.impl.actions.XmlAction.run(XmlAction.java:67) ~[moqui-framework-2.1.1-rc2.jar:2.1.1-rc2]

Caused by: java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended

        at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:494) ~[ojdbc-8.jar:12.2.0.1.0]
        at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:446) ~[ojdbc-8.jar:12.2.0.1.0]
        at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1054) ~[ojdbc-8.jar:12.2.0.1.0]
        at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:623) ~[ojdbc-8.jar:12.2.0.1.0]
        at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:252) ~[ojdbc-8.jar:12.2.0.1.0]
        at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:612) ~[ojdbc-8.jar:12.2.0.1.0]
        at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:226) ~[ojdbc-8.jar:12.2.0.1.0]
        at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:59) ~[ojdbc-8.jar:12.2.0.1.0]
        at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:747) ~[ojdbc-8.jar:12.2.0.1.0]
        at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:904) ~[ojdbc-8.jar:12.2.0.1.0]
        at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1082) ~[ojdbc-8.jar:12.2.0.1.0]
        at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3780) ~[ojdbc-8.jar:12.2.0.1.0]
        at oracle.jdbc.driver.T4CPreparedStatement.executeInternal(T4CPreparedStatement.java:1343) ~[ojdbc-8.jar:12.2.0.1.0]
        at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3822) ~[ojdbc-8.jar:12.2.0.1.0]
        at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1165) ~[ojdbc-8.jar:12.2.0.1.0]
        at bitronix.tm.resource.jdbc.proxy.PreparedStatementJavaProxy.executeQuery(PreparedStatementJavaProxy.java:102) ~[btm-3.0.0-SNAPSHOT.jar:3.0.0-SNAPSHOT]
        at org.moqui.impl.entity.EntityQueryBuilder.executeQuery(EntityQueryBuilder.java:91) ~[moqui-f
amirmf commented 6 years ago

i fixed this with developing this method in EntityFindBuilder class

    public void addLimitOffset(Integer limit, Integer offset) {
        if (limit == null && offset == null) return;

        MNode databaseNode = this.efi.getDatabaseNode(mainEntityDefinition.getEntityGroupName());
        // if no databaseNode do nothing, means it is not a standard SQL/JDBC database
        if (databaseNode != null) {
            String offsetStyle = databaseNode.attribute("offset-style");
            if ("limit".equals(offsetStyle)) {
                // use the LIMIT/OFFSET style
                sqlTopLevel.append(" LIMIT ").append(limit != null && limit > 0 ? limit : "ALL");
                sqlTopLevel.append(" OFFSET ").append(offset != null ? offset : 0);
            }else if ("oracle".equals(offsetStyle)) {
                sqlTopLevel.insert(sqlTopLevel.indexOf(" FROM "),", ROWNUM RN");
                sqlTopLevel.insert(0,"SELECT * FROM (");
                Integer lastIndex= offset+limit;
                sqlTopLevel.append(") TEMPQRY WHERE TEMPQRY.RN >= "+ offset +" AND TEMPQRY.RN <= "+ lastIndex);

            }else if (offsetStyle == null || offsetStyle.length() == 0 || "fetch".equals(offsetStyle)) {
                // use SQL2008 OFFSET/FETCH style by default
                sqlTopLevel.append(" OFFSET ").append(offset != null ? offset.toString() : '0').append(" ROWS");
                if (limit != null) sqlTopLevel.append(" FETCH FIRST ").append(limit).append(" ROWS ONLY");
            }
            // do nothing here for offset-style=cursor, taken care of in EntityFindImpl
        }
    }
amirmf commented 5 years ago

Hi @jonesde I've changed a few lines of your query builder class to make Moqui compatible with oracle. You've used few SQL commands which aren't standard query for example: OFFSET & ... I have just changed all specific queries to standard queries. Here's the link of new files: https://we.tl/t-TMjWISAG0o

i've test the new classes it's working fine.

jonesde commented 5 years ago

Could you submit this as a patch so I don't have to manually diff? To do this just run something like 'git diff > issue327.patch'. You can also attach things to comments on GitHub, just drag them into the little grey area below where you type in comments as mentioned in that box (says 'Attach files by...').

I'm not sure what you mean by specific and standard queries, but I'll take a look at your patch to see. For what it's worth, my experience with Oracle is that the word 'standard' just doesn't apply... if they supported the SQL2008 standard the 'fetch' offset-style would work. :)