Menu

#36 SQL exception using recompute

open
nobody
None
Max
recompute
normal
2015-02-18
2012-10-22
Sira Imatia
No

Hi,

We are having some problems using recompute. We would like recalcule the "amountTotal" of 'Alpha and Sons' customer. To do that we are using the following code:

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("OntimizeLogicTesting");

Set<String> entityNamesToCheck = new HashSet<String>();
entityNamesToCheck.add("buslogicdemo.data.pojo.Purchaseorder");

HashMap<String, String> entityCriteria = new HashMap<String, String>();
entityCriteria.put("buslogicdemo.data.pojo.Purchaseorder", "customer.name = 'Alpha and Sons'");

Configuration recomputeConfiguration = new Configuration();
recomputeConfiguration.setEntityNamesToCheck(entityNamesToCheck);
recomputeConfiguration.setEntityCriteria(entityCriteria);

Engine engine = new Engine(recomputeConfiguration, entityManagerFactory);
engine.fix();

This code throws an SQL Exception. This is the console log with the exception:

abl.recomp - Beginning fix
abl.depend - Creating new LogicAnalysisManager for Engine com.autobizlogic.abl.engine.LogicEngine@b54ef7
abl.depend - Analyzing dependencies for Java logic class : buslogicdemo.businesslogic.pojo.PurchaseorderLogic
Ordered rules:
Sum buslogicdemo.data.pojo.Purchaseorder#deriveAmountTotal, summing: amount over role lineitems
abl.recomp - Checking aggregate: Sum buslogicdemo.data.pojo.Purchaseorder#deriveAmountTotal, summing: amount over role lineitems
org.hibernate.SQL - 
    update
        Purchaseorder 
    set
        amount_total=coalesce((select
            sum(lineitems1_.amount) 
        from
            lineitem lineitems1_ 
        where
            Purchaseorder.order_number=lineitems1_.order_number),
        0) 
    where
        (
            amount_total is null
        ) 
        and coalesce((select
            sum(lineitems2_.amount) 
        from
            lineitem lineitems2_ 
        where
            Purchaseorder.order_number=lineitems2_.order_number), 0)<>0 
        and purchaseor0_.customer_name='Alpha and Sons'
org.hibernate.util.JDBCExceptionReporter - User lacks privilege or object not found: PURCHASEOR0_.CUSTOMER_NAME
Exception in thread "main" java.lang.RuntimeException: org.hibernate.exception.SQLGrammarException: could not execute update query
    at com.autobizlogic.recompute.fix.FixTask.run(FixTask.java:64)
    at com.autobizlogic.recompute.Engine.fix(Engine.java:135)
    at test.MainTest.recompute(MainTest.java:329)
    at test.MainTest.main(MainTest.java:59)
Caused by: org.hibernate.exception.SQLGrammarException: could not execute update query
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.hql.ast.exec.BasicExecutor.execute(BasicExecutor.java:110)
    at org.hibernate.hql.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:423)
    at org.hibernate.engine.query.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:283)
    at org.hibernate.impl.SessionImpl.executeUpdate(SessionImpl.java:1288)
    at org.hibernate.impl.QueryImpl.executeUpdate(QueryImpl.java:117)
    at com.autobizlogic.recompute.fix.AggregateFix.executeExpression(AggregateFix.java:104)
    at com.autobizlogic.recompute.fix.FixTask.fix(FixTask.java:90)
    at com.autobizlogic.recompute.fix.FixTask.run(FixTask.java:61)
    ... 3 more
Caused by: java.sql.SQLException: User lacks privilege or object not found: PURCHASEOR0_.CUSTOMER_NAME
    at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCPreparedStatement.<init>(Unknown Source)
    at org.hsqldb.jdbc.JDBCConnection.prepareStatement(Unknown Source)
    at com.mchange.v2.c3p0.impl.NewProxyConnection.prepareStatement(NewProxyConnection.java:213)
    at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:534)
    at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:116)
    at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109)
    at org.hibernate.hql.ast.exec.BasicExecutor.execute(BasicExecutor.java:88)
    ... 10 more

Are we using the right criteria or is there a better way to recalculate this information?

Cheers,
Sira

Discussion

  • Automated Business Logic

    Well, this sum is for Purchaseorder, but the where clause is for Customer. Could you try specifying it as:

    entityCriteria.put("buslogicdemo.data.pojo.Purchaseorder", "p.customer.name = 'Alpha and Sons'");

    because p is the alias we use in the HQL query. If this does not work for you, let me know and we'll figure something out.

     
  • Sira Imatia

    Sira Imatia - 2012-10-29

    Hi,

    We have changed the criteria but we have gotten the same exception. To get more information, we've activated the HQL log4Java logger, and we were able to see the HQL code generated by Recompute.

    We have following HQL sentence with the old criteria:

    org.hibernate.hql.ast.QueryTranslatorImpl - parse() - HQL: update buslogicdemo.data.pojo.Purchaseorder as p set amountTotal = coalesce((select sum(c.amount) from p.lineitems as c ), 0) WHERE p.amountTotal IS NULL AND coalesce((select sum(c.amount) from p.lineitems as c ), 0) <> 0 AND (customer.name = 'Alpha and Sons')
    

    With your suggested criteria, we have this HQL sentence:

    org.hibernate.hql.ast.QueryTranslatorImpl - parse() - HQL: update buslogicdemo.data.pojo.Purchaseorder as p set amountTotal = coalesce((select sum(c.amount) from p.lineitems as c ), 0) WHERE p.amountTotal IS NULL AND coalesce((select sum(c.amount) from p.lineitems as c ), 0) <> 0 AND (p.customer.name = 'Alpha and Sons')
    

    But the SQL generated by Hibernate is the same in both cases:

    org.hibernate.SQL - 
    update
        Purchaseorder 
    set
        amount_total=coalesce((select
            sum(lineitems1_.amount) 
        from
            lineitem lineitems1_ 
        where
            Purchaseorder.order_number=lineitems1_.order_number),
        0) 
    where
        (
            amount_total is null
        ) 
        and coalesce((select
            sum(lineitems2_.amount) 
        from
            lineitem lineitems2_ 
        where
            Purchaseorder.order_number=lineitems2_.order_number), 0)<>0 
        and purchaseor0_.customer_name='Alpha and Sons'
    

    Cheers,
    Sira

     
  • Sira Imatia

    Sira Imatia - 2013-01-07

    Hi,

    I was reviewing this bug and I think I get the cause of the exception: It seems Hibernate doesn't generate the SQL sentence in right way from Recompute HQL sentence.

    When we use Recompute with the following criteria:

    entityCriteria.put("buslogicdemo.data.pojo.Purchaseorder", "customer.name = 'Alpha and Sons'")
    

    Recompute generates this HQL sentence:

    update buslogicdemo.data.pojo.Purchaseorder as p 
    set amountTotal = coalesce((select sum(c.amount) from p.lineitems as c ), 0) 
    WHERE p.amountTotal IS NULL 
        AND coalesce((select sum(c.amount) from p.lineitems as c ), 0) <> 0 
        AND (customer.name = 'Alpha and Sons')
    

    Then Hibernate generates the following SQL sentence:

    update
        Purchaseorder 
    set
        amount_total=coalesce((select
            sum(lineitems1_.amount) 
        from
            lineitem lineitems1_ 
        where
            Purchaseorder.order_number=lineitems1_.order_number),
        0) 
    where
        (
            amount_total is null
        ) 
        and coalesce((select
            sum(lineitems2_.amount) 
        from
            lineitem lineitems2_ 
        where
            Purchaseorder.order_number=lineitems2_.order_number), 0)<>0 
        and purchaseor0_.customer_name='Alpha and Sons'
    

    When Hibernate executes that SQL sentence, it will get the following Exception:

    org.hibernate.util.JDBCExceptionReporter - User lacks privilege or object not found: PURCHASEOR0_.CUSTOMER_NAME
    

    ...

    I did a test executing the Recompute's HQL sentence in an independent code but I allways got the above exception. Then I changed the order of conditions, putting the Recompute criteria condition first and I get the following HQL sentence:

    update buslogicdemo.data.pojo.Purchaseorder as p 
    set amountTotal = coalesce((select sum(c.amount) from p.lineitems as c ), 0) 
    WHERE (customer.name = 'Alpha and Sons')
        AND  p.amountTotal IS NULL
    AND coalesce((select sum(c.amount) from p.lineitems as c ), 0) <> 0
    

    I don't know why but Hibernate generates a different SQL sentence to this HQL and it doesn't throw any exception. This is the generated SQL without exceptions:

    update
        Purchaseorder 
    set
        amount_total=coalesce((select
            sum(lineitems1_.amount) 
        from
            lineitem lineitems1_ 
        where
            Purchaseorder.order_number=lineitems1_.order_number),
        0) 
    where
        customer_name='Alpha and Sons' 
        and (
            amount_total is null
        ) 
        and coalesce((select
            sum(lineitems2_.amount) 
        from
            lineitem lineitems2_ 
        where
            Purchaseorder.order_number=lineitems2_.order_number), 0)<>0
    

    This is the main method used to check the HQL sentence in our persistence unit. This method will throw an exception but if you change the order of HQL conditions it will run fine:

    public static void main(String[] args){
    
        EntityManagerFactory entityManagerFactory = 
            Persistence.createEntityManagerFactory("OntimizeLogicTesting");
        EntityManager em = entityManagerFactory.createEntityManager();
    
        Session session = (Session) em.getDelegate();
    Transaction t = session.beginTransaction();
    
        String finalHql =   "update buslogicdemo.data.pojo.Purchaseorder as p set " +
            " amountTotal = coalesce((select sum(c.amount) from p.lineitems as c ), 0) " +
            " WHERE p.amountTotal IS NULL " +
            " AND coalesce((select sum(c.amount) from p.lineitems as c ), 0) <> 0 " +
            " AND (customer.name = 'Alpha and Sons')";
    
        org.hibernate.Query q = session.createQuery(finalHql);
        int numBadRows = q.executeUpdate();
        t.commit();
    
    }
    

    I hope this will help you to check the bug.

    Cheers,
    Sira

     

Anonymous
Anonymous

Add attachments
Cancel