-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 14 posts ] 
Author Message
 Post subject: Formula property
PostPosted: Mon Apr 18, 2005 10:34 am 
Beginner
Beginner

Joined: Sun Feb 20, 2005 12:14 am
Posts: 49
I have two classes - Product and Sku. A product can have one or more skus. In product I need to add a property that gets calculated from data thats held by related Skus. For this I added a property called lowestPrice in Product that uses a formula. When I retreive a product I expected to have the lowestPrice calcuated using the formula, but I get null.

I read quite a few posts, but I seem to be doing all that is necessary.

What am I missing out?

Hibernate version: 3.0

Mapping documents:
Code:
    <class name="Product" table="product">
      <id name="id" unsaved-value="null" type="string" length="32">
           <generator class="uuid"/>
      </id>

       <version name="version" type="long" unsaved-value="null"/>
       
        <property name="name" type="string" not-null="true" unique="true"/>
        <property name="shippingPrice" type="double" not-null="true"/>
        <property name="lowestPrice" type="double">
           <formula>
              (
              select min(price)
              from Product as prod, Sku as sku
              where prod.id = sku.productId
              )
           </formula>
        </property>
    </class>


What am I missing out?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 18, 2005 11:32 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
stacktrace? generated sql?

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 18, 2005 1:09 pm 
Beginner
Beginner

Joined: Sun Feb 20, 2005 12:14 am
Posts: 49
I am running a JUnit test case to test the functionality out. The test case first sets up the data. A category with another category within it. The inner category has one product. The product is related to two skus. The formula needs to calculate the min(sku.price) and assign it to the lowestPrice property. The test case prints the value of the lowestPrice and finally the test case deletes all the data fed to the database for peforming the test.

Complete mapping files for Product and Sku:
Code:
   <!-- PRODUCT -->
    <class name="Product" table="product">
      <id name="id" unsaved-value="null" type="string" length="32">
           <generator class="uuid"/>
      </id>

       <version name="version" type="long" unsaved-value="null"/>
       
        <property name="name" type="string" not-null="true" unique="true"/>
        <property name="shippingPrice" type="double" not-null="true"/>
        <property name="lowestPrice" type="double">
           <formula>
              (
              select min(sku.price)
              from Product as prod, Sku as sku
              where prod.id = sku.productId
              )
           </formula>
        </property>

        <map name="descriptions"
            access="field"
            lazy="true"
            cascade="all">
              <key column="entityId" foreign-key="none"/>
            <map-key formula="type" type="string" length="32"/>
            <one-to-many class="Description"/>
        </map>

        <property name="discontinued" type="boolean" not-null="true"/>
        <property name="active" type="boolean" not-null="true"/>
       
        <set name="skus" access="field" lazy="true" cascade="all" inverse="true">
           <key column="productId" not-null="true"/>
           <one-to-many class="Sku"/>
        </set>

       <set name="parentCategories" access="field" table="category_product" inverse="true" lazy="true">
         <key column="productId" not-null="true"/>
         <many-to-many column="categoryId"
                       class="Category"/>
      </set>
      
      <map name="flags"
            access="field"
          table="product_flag"
          cascade="all"
          lazy="true">
          <key column="productId" not-null="true"/>
          <index column="name" type="string" length="32"/>
          <element column="value" type="boolean" not-null="true"/>
      </map>
   </class>

   <!-- SKU -->
   <class name="Sku" table="sku">
      <id name="id" unsaved-value="null" type="string" length="32">
           <generator class="uuid"/>
      </id>
   
      <version name="version" type="long" unsaved-value="null"/>
      
      <property name="partNumber" type="string" not-null="true" unique="true"/>
      <property name="manufacturePN" type="string"/>
      <property name="weight" type="double"/>
      <property name="price" type="double" not-null="true"/>
      <property name="msrp" type="double"/>
      <property name="displayName" type="string" not-null="true"/>
      <property name="active" type="boolean" not-null="true"/> 
      <property name="discontinued" type="boolean" not-null="true"/>
                 
      <many-to-one
         name="product"
         column="productId"
         class="Product" not-null="true"/>
   </class>


Generated sql:
Code:
INFO  - Hibernate 3.0
INFO  - hibernate.properties not found
INFO  - using CGLIB reflection optimizer
INFO  - using JDK 1.4 java.sql.Timestamp handling
INFO  - configuring from resource: /hibernate.cfg.xml
INFO  - Configuration resource: /hibernate.cfg.xml
INFO  - Mapping resource: com/ac/tan/beans/Beans.hbm.xml
INFO  - Mapping class: com.ac.tan.beans.Category -> category
INFO  - Mapping collection: com.ac.tan.beans.Category.products -> category_product
INFO  - Mapping class: com.ac.tan.beans.Description -> description
INFO  - Mapping class: com.ac.tan.beans.Product -> product
INFO  - Mapping collection: com.ac.tan.beans.Product.parentCategories -> category_product
INFO  - Mapping collection: com.ac.tan.beans.Product.flags -> product_flag
INFO  - Mapping class: com.ac.tan.beans.Sku -> sku
INFO  - Mapping class: com.ac.tan.beans.Contact -> contact
INFO  - Mapping class: com.ac.tan.beans.Customer -> customer
INFO  - Mapping class: com.ac.tan.beans.Cart -> cart
INFO  - Mapping class: com.ac.tan.beans.CartItem -> cartitem
INFO  - Mapping class: com.ac.tan.beans.CreditCard -> creditcard
INFO  - Mapping class: com.ac.tan.beans.OrderItem -> orderitem
INFO  - Mapping class: com.ac.tan.beans.Destination -> destination
INFO  - Mapping class: com.ac.tan.beans.OrderItemDestination -> orderitem_destination
INFO  - Mapping class: com.ac.tan.beans.Order -> order
INFO  - Configured SessionFactory: null
INFO  - processing extends queue
INFO  - processing collection mappings
INFO  - Mapping collection: com.ac.tan.beans.Category.subCategories -> category
INFO  - Mapping collection: com.ac.tan.beans.Product.descriptions -> description
INFO  - Mapping collection: com.ac.tan.beans.Product.skus -> sku
INFO  - Mapping collection: com.ac.tan.beans.Customer.contacts -> contact
INFO  - Mapping collection: com.ac.tan.beans.Customer.orders -> order
INFO  - Mapping collection: com.ac.tan.beans.Customer.creditCards -> creditcard
INFO  - Mapping collection: com.ac.tan.beans.Cart.cartItems -> cartitem
INFO  - Mapping collection: com.ac.tan.beans.OrderItem.orderItemDestinations -> orderitem_destination
INFO  - Mapping collection: com.ac.tan.beans.Destination.orderItemDestinations -> orderitem_destination
INFO  - Mapping collection: com.ac.tan.beans.Order.orderItems -> orderitem
INFO  - Mapping collection: com.ac.tan.beans.Order.destinations -> destination
INFO  - processing association property references
INFO  - processing foreign key constraints
INFO  - Using dialect: org.hibernate.dialect.MySQLDialect
INFO  - Maximum outer join fetch depth: 2
INFO  - Default batch fetch size: 1
INFO  - Generate SQL with comments: disabled
INFO  - Order SQL updates by primary key: disabled
INFO  - Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
INFO  - Using ASTQueryTranslatorFactory
INFO  - Query language substitutions: {}
INFO  - C3P0 using driver: com.mysql.jdbc.Driver at URL: jdbc:mysql://localhost/test3
INFO  - Connection properties: {user=someUser, password=****}
INFO  - autocommit mode: false
Initializing c3p0 pool... com.mchange.v2.c3p0.PoolBackedDataSource@12bb7e0 [ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@15a0305 [ acquireIncrement -> 3, autoCommitOnClose -> false, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, maxIdleTime -> 0, maxPoolSize -> 15, maxStatements -> 0, minPoolSize -> 3, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@134f69a [ description -> null, driverClass -> null, factoryClassLocation -> null, jdbcUrl -> jdbc:mysql://localhost/test3, properties -> {user=someUser, password=*******} ] , propertyCycle -> 300, testConnectionOnCheckout -> false ] , factoryClassLocation -> null, numHelperThreads -> 3 ]
INFO  - JDBC batch size: 15
INFO  - JDBC batch updates for versioned data: disabled
INFO  - Scrollable result sets: enabled
INFO  - JDBC3 getGeneratedKeys(): enabled
INFO  - Transaction strategy: org.hibernate.transaction.JDBCTransactionFactory
INFO  - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
INFO  - Automatic flush during beforeCompletion(): disabled
INFO  - Automatic session close at end of transaction: disabled
INFO  - Cache provider: org.hibernate.cache.EhCacheProvider
INFO  - Second-level cache: enabled
INFO  - Optimize cache for minimal puts: disabled
INFO  - Structured second-level cache entries: enabled
INFO  - Query cache: disabled
INFO  - Echoing all SQL to stdout
INFO  - Statistics: disabled
INFO  - Deleted entity synthetic identifier rollback: disabled
INFO  - Default entity-mode: pojo
INFO  - building session factory
WARN  - No configuration found. Configuring ehcache from ehcache-failsafe.xml found in the classpath: jar:file:/C:/Documents%20and%20Settings/mkhumri/Development/tan/default-site/WEB-INF/lib/ehcache-1.1.jar!/ehcache-failsafe.xml
INFO  - Not binding factory to JNDI, no JNDI name configured
INFO  - Using dialect: org.hibernate.dialect.MySQLDialect
INFO  - C3P0 using driver: com.mysql.jdbc.Driver at URL: jdbc:mysql://localhost/test3
INFO  - Connection properties: {user=someUser, password=****}
INFO  - autocommit mode: false
INFO  - Running hbm2ddl schema update
INFO  - fetching database metadata
Initializing c3p0 pool... com.mchange.v2.c3p0.PoolBackedDataSource@64ab4d [ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@49d67c [ acquireIncrement -> 3, autoCommitOnClose -> false, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, maxIdleTime -> 0, maxPoolSize -> 15, maxStatements -> 0, minPoolSize -> 3, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@12a55aa [ description -> null, driverClass -> null, factoryClassLocation -> null, jdbcUrl -> jdbc:mysql://localhost/test3, properties -> {user=someUser, password=*******} ] , propertyCycle -> 300, testConnectionOnCheckout -> false ] , factoryClassLocation -> null, numHelperThreads -> 3 ]
INFO  - updating schema
INFO  - processing extends queue
INFO  - processing collection mappings
INFO  - processing association property references
INFO  - processing foreign key constraints
INFO  - table found: .order
INFO  - columns: [creditcardid, id, customerid, version]
INFO  - foreign keys: [fk651874e1d2dfd4a, fk651874e65ee8540]
INFO  - indexes: [primary, fk651874e1d2dfd4a, fk651874e65ee8540]
INFO  - table found: .cart
INFO  - columns: [id, version]
INFO  - foreign keys: []
INFO  - indexes: [primary]
INFO  - table found: .cartitem
INFO  - columns: [cartid, skuid, quantity, id, version]
INFO  - foreign keys: [fk6d663383a1cce, fk6d6633cf9dd842]
INFO  - indexes: [primary, fk6d663383a1cce, fk6d6633cf9dd842]
INFO  - table found: .category
INFO  - columns: [parentid, description, image, name, id, version]
INFO  - foreign keys: [fk302bcfea059c036]
INFO  - indexes: [fk302bcfea059c036, primary]
INFO  - table found: .category_product
INFO  - columns: [productid, categoryid]
INFO  - foreign keys: [fkb88a52aea795af8a, fkb88a52aee3396ce6]
INFO  - indexes: [fkb88a52aea795af8a, primary, fkb88a52aee3396ce6]
INFO  - table found: .contact
INFO  - columns: [phonenumber, first, id, entitytype, version, company, street2, last, street1, entityid, emailaddress, state, zip, city]
INFO  - foreign keys: []
INFO  - indexes: [primary]
INFO  - table found: .creditcard
INFO  - columns: [cardtype, cardnumber, nameoncard, expiry, id, version, customerid, street2, street1, securitycode, state, zip, city]
INFO  - foreign keys: [fkde6401891d2dfd4a]
INFO  - indexes: [fkde6401891d2dfd4a, cardnumber, primary]
INFO  - table found: .customer
INFO  - columns: [password, last, first, emailaddress, id, company, version]
INFO  - foreign keys: []
INFO  - indexes: [primary, emailaddress]
INFO  - table found: .description
INFO  - columns: [text, type, entityid, entitytype, id, version]
INFO  - foreign keys: []
INFO  - indexes: [primary]
INFO  - table found: .destination
INFO  - columns: [phonenumber, first, orderid, id, version, company, street2, last, street1, emailaddress, state, zip, city]
INFO  - foreign keys: [fkaac6440e96bb4d24]
INFO  - indexes: [primary, fkaac6440e96bb4d24]
INFO  - table found: .orderitem
INFO  - columns: [price, description, orderid, partnumber, quantity, id, version]
INFO  - foreign keys: [fke8b2ab6196bb4d24]
INFO  - indexes: [primary, fke8b2ab6196bb4d24]
INFO  - table found: .orderitem_destination
INFO  - columns: [destinationid, orderitemid, quantity, id, version]
INFO  - foreign keys: [fkd862443050c470e4, fkd862443017c122a]
INFO  - indexes: [primary, fkd862443017c122a, fkd862443050c470e4]
INFO  - table found: .product
INFO  - columns: [active, shippingprice, discontinued, name, id, version]
INFO  - foreign keys: []
INFO  - indexes: [primary, name]
INFO  - table found: .product_flag
INFO  - columns: [value, productid, name]
INFO  - foreign keys: [fk3c72a8bce3396ce6]
INFO  - indexes: [fk3c72a8bce3396ce6, primary]
INFO  - table found: .sku
INFO  - columns: [active, productid, manufacturepn, price, discontinued, partnumber, displayname, weight, id, msrp, version]
INFO  - foreign keys: [fk1bd1de3396ce6]
INFO  - indexes: [primary, fk1bd1de3396ce6, partnumber]
INFO  - schema update complete
INFO  - Checking 0 named queries
Hibernate: insert into category (version, name, description, image, parentId, id) values (?, ?, ?, ?, ?, ?)
Hibernate: select category0_.id as col_0_0_ from category category0_ where (category0_.name=?)
Hibernate: insert into category (version, name, description, image, parentId, id) values (?, ?, ?, ?, ?, ?)
Hibernate: update category set version=?, name=?, description=?, image=?, parentId=? where id=? and version=?
Hibernate: select category0_.id as col_0_0_ from category category0_ where (category0_.name=?)
Hibernate: insert into category (version, name, description, image, parentId, id) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into product (version, name, shippingPrice, discontinued, active, id) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into description (version, type, text, entityType, entityId, id) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into sku (version, partNumber, manufacturePN, weight, price, msrp, displayName, active, discontinued, productId, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into sku (version, partNumber, manufacturePN, weight, price, msrp, displayName, active, discontinued, productId, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: update category set version=?, name=?, description=?, image=?, parentId=? where id=? and version=?
Hibernate: insert into category_product (categoryId, productId) values (?, ?)
Hibernate: update description set entityId=? where id=?
Hibernate: insert into product_flag (productId, name, value) values (?, ?, ?)
#DEBUG: lowest price = null
Hibernate: select category0_.id as col_0_0_ from category category0_ where (category0_.name=?)
Hibernate: delete from category_product where categoryId=?
Hibernate: update description set entityId=null where entityId=?
Hibernate: delete from product_flag where productId=?
Hibernate: delete from description where id=? and version=?
Hibernate: delete from sku where id=? and version=?
Hibernate: delete from sku where id=? and version=?
Hibernate: delete from product where id=? and version=?
Hibernate: delete from category where id=? and version=?
Hibernate: delete from category where id=? and version=?
Hibernate: delete from category where id=? and version=?


JUnit test case:
Code:
   public void testProductLowestPrice()
   {
      DBManager.beginTransaction();

      try
      {
         CategoryDAO cdao = daoFactory.getCategoryDAO();
         SkuDAO sdao = daoFactory.getSkuDAO();
         ProductDAO pdao = daoFactory.getProductDAO();

         Category cat = new Category("Audio",               
                  "This category maintains the audio products.", null);
         cdao.insert(cat);

         Iterator it = cdao.findAllByName("Audio");
         Category p = (it != null && it.hasNext())? (Category)it.next() : null;
         cat = new Category("Bose",               
                  "This category maintains the bose products.", "bose-logo.jpg");
         p.addSubCategory(cat);

         cdao.insert(cat);
         cdao.update(p);

         it = cdao.findAllByName("Bose");
         Category p1 = (it != null && it.hasNext())? (Category)it.next() : null;
         Category cat1 = new Category("Bose-xtinct",               
                  "This category maintains the bose products for cars.",
               "bose-xtinct.jpg");
         Product pr1 = new Product("Prod1", new Double(9.5), true, false);
         pr1.addDescription(new Description(Description.SHORT,
               "Bose with advanced sub woofer and trebble."));
         pr1.addFlag("doNotDisplay", true);

         Sku sku1 = new Sku("prd-765", "bing ling ding", "bing ling", 128.9,
               89.79, 100, true, false);

         Sku sku2 = new Sku("prd-09", "adfa adfa sda", "afd fdf", 11.9,
               12, 50, true, false);         

         p1.addSubCategory(cat1);
         pr1.addSku(sku1);
         pr1.addSku(sku2);
      
         cat1.addProduct(pr1);
                  
         String catId = cdao.insert(cat1);
         cdao.update(p1);
         
         sdao.insert(sku1);
         sdao.insert(sku2);

         DBManager.commitTransaction();
         DBManager.beginTransaction();         

         pr1 = (Product)pdao.load(pr1.getId());
         if(pr1.getLowestPrice() != null)          
           System.out.println("#DEBUG: lowest price = " + pr1.getLowestPrice().doubleValue());
         else
           System.out.println("#DEBUG: lowest price = null");
         
         //Cleanup
         Iterator it4 = cdao.findAllByName("Audio");
         while(it4 != null && it4.hasNext())
         {
            Category delCategory = (Category)it4.next();         
            Category delCategoryParent = delCategory.getParent();
   
            if (delCategoryParent != null)
            {
               delCategoryParent.removeSubCategory(delCategory);
            }
   
            cdao.delete(delCategory);
         }
         
         DBManager.commitTransaction();
      }
      catch (Exception ex)
      {
         ex.printStackTrace();
         DBManager.rollbackTransaction();
         Assert.fail();
      }
   }


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 18, 2005 1:34 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
here is the problem:
Code:
         pr1 = (Product)pdao.load(pr1.getId());
         if(pr1.getLowestPrice() != null)           
           System.out.println("#DEBUG: lowest price = " + pr1.getLowestPrice().doubleValue());
         else
           System.out.println("#DEBUG: lowest price = null");


As the field is calculated by the database (formula is SQL), you must get pr1 from a new session or ask hibernate to refresh it (session.refresh(pr1)).

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 18, 2005 1:39 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
have you noticed that your formula is going to be executed even if you don't need to acceed this calculated field?
this is bad for performance.
BUT hibernate is the best ORM in the world ;) , you should just declare this _formula_ as a lazy property (don't forget instrumentation): in some case (like yours) this is a really great feature.

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 18, 2005 3:17 pm 
Beginner
Beginner

Joined: Sun Feb 20, 2005 12:14 am
Posts: 49
Thankyou for the pointers. I modified the code to refresh the object and I also specified lazy to be true which makes sense.

I get an exception now. From what I understand the problem is in the generated SQL:

Code:
select
   product0_.id as id0_,
   product0_.version as version3_0_,
   product0_.name as name3_0_,
   product0_.shippingPrice as shipping4_3_0_,
   product0_.discontinued as disconti5_3_0_,
   product0_.active as active3_0_,
      (
         select
         min(sku.price)
           from
         product0_.product product0_.prod, product0_.sku product0_.sku
           where
         prod.id = sku.productId
      )
      as formula0_0_
from
   product product0_
where
   product0_.id=?


In the above SQL in the subselect why does hibernate say "from product_0.product product0_.prod, product0_sku product0_.sku .. " ?

I maybe wrong, but why is this exception being thrown?

Exception being thrown:
Code:
Hibernate: select product0_.id as id0_, product0_.version as version3_0_, product0_.name as name3_0_, product0_.shippingPrice as shipping4_3_0_, product0_.discontinued as disconti5_3_0_, product0_.active as active3_0_,
              (
              select min(sku.price)
              from product0_.product product0_.prod, product0_.sku product0_.sku
              where prod.id = sku.productId
              )
            as formula0_0_ from product product0_ where product0_.id=?
WARN  - SQL Error: 1064, SQLState: 42000
ERROR - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.prod, product0_.sku product0_.sku
              where prod.id = sku.productId
    ' at line 4
INFO  - Error performing load command
org.hibernate.exception.SQLGrammarException: could not load an entity: [com.ac.tan.beans.Product#402881ef0356aad5010356aaedc50004]
   at org.hibernate.exception.ErrorCodeConverter.convert(ErrorCodeConverter.java:70)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.loader.Loader.loadEntity(Loader.java:1285)
   at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:141)
   at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:126)
   at org.hibernate.persister.entity.BasicEntityPersister.load(BasicEntityPersister.java:2496)
   at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:387)
   at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:368)
   at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:166)
   at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:140)
   at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:119)
   at org.hibernate.impl.SessionImpl.immediateLoad(SessionImpl.java:577)
   at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:59)
   at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:80)
   at org.hibernate.proxy.CGLIBLazyInitializer.intercept(CGLIBLazyInitializer.java:134)
   at com.ac.tan.beans.Product$$EnhancerByCGLIB$$f84cee7c.getLowestPrice(<generated>)
   at com.ac.tan.persistence.daos.TestProduct.testProductLowestPrice(TestProduct.java:251)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at junit.framework.TestCase.runTest(TestCase.java:154)
   at junit.framework.TestCase.runBare(TestCase.java:127)
   at junit.framework.TestResult$1.protect(TestResult.java:106)
   at junit.framework.TestResult.runProtected(TestResult.java:124)
   at junit.framework.TestResult.run(TestResult.java:109)
   at junit.framework.TestCase.run(TestCase.java:118)
   at junit.framework.TestSuite.runTest(TestSuite.java:208)
   at junit.framework.TestSuite.run(TestSuite.java:203)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:421)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:305)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:186)
Caused by: java.sql.SQLException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.prod, product0_.sku product0_.sku
              where prod.id = sku.productId
    ' at line 4
   at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2847)
   at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1531)
   at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1622)
   at com.mysql.jdbc.Connection.execSQL(Connection.java:2376)
   at com.mysql.jdbc.Connection.execSQL(Connection.java:2297)
   at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1860)
   at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1705)
   at com.mchange.v2.sql.filter.FilterPreparedStatement.executeQuery(FilterPreparedStatement.java:68)
   at com.mchange.v2.c3p0.impl.C3P0PooledConnection$2.executeQuery(C3P0PooledConnection.java:567)
   at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:118)
   at org.hibernate.loader.Loader.getResultSet(Loader.java:1197)
   at org.hibernate.loader.Loader.doQuery(Loader.java:366)
   at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:206)
   at org.hibernate.loader.Loader.loadEntity(Loader.java:1271)
   ... 29 more


Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 18, 2005 4:59 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
1- are you sure your formula is 100% SQL (you can only use column and table names) ?
2- does your mySQL release allow subselect ?
3- what if you copy/paste the generated sql into your db client (just replace ? by the id you need)

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 18, 2005 7:06 pm 
Beginner
Beginner

Joined: Sun Feb 20, 2005 12:14 am
Posts: 49
1. Yes, the formula is 100% SQL. I am only using table and column names.
2. Yes, the mySQL version i am using is allowing subselects.
3. When I copy paste the generated SQL by Hibernate I get an error at the mysql prompt. [Note: When I modify the Hibernate generated SQL and run it on my MySQL prompt the query works proving that my version of MySQL supports subselects.]

Hibernate generates the following sql:
Code:
select
   product0_.id as id0_,
   product0_.version as version3_0_,
   product0_.name as name3_0_,
   product0_.shippingPrice as shipping4_3_0_,
   product0_.discontinued as disconti5_3_0_,
   product0_.active as active3_0_,
      (
         select min(s.price)
           from product0_.product product0_.as product0_.p, product0_.sku product0_.as product0_.s
           where p.id = s.productId
      )
      as formula0_0_
from
   product product0_
where
   product0_.id="402881ef035770cf01035770e77f0004";


The above sql throws the following exception at mysql prompt:
Code:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.as p
roduct0_.p, product0_.sku product0_.as product0_.s
                where p.id = s.' at line 10


[Note the product id above is something i tested with against my database. Hibernate has a ? mark in its place]

I modified the hibernate sql to show that subselects work in my version of mysql:
Code:
select
   product0_.id as id0_,
   product0_.version as version3_0_,
   product0_.name as name3_0_,
   product0_.shippingPrice as shipping4_3_0_,
   product0_.discontinued as disconti5_3_0_,
   product0_.active as active3_0_,
      (
         select
         min(sku.price)
           from
         product prod, sku sku
           where
         prod.id = sku.productId
      )
      as formula0_0_
from
   product product0_
where
   product0_.id="402881ef035770cf01035770e77f0004";

The above sql works fine on my mysql prompt.

Does this mean that there is a bug in the sql generation in Hibernate for a formula?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 18, 2005 8:04 pm 
Beginner
Beginner

Joined: Sun Feb 20, 2005 12:14 am
Posts: 49
Alright!, I resolved this by pure CHANCE. This seems like a definite Hibernate bug.

Explanation:

This fails:
Code:
        <property name="lowestPrice" type="double">
           <formula>
              ( select MIN(s.price)
                from SKU s where s.productId = id )
           </formula>
        </property>


This works:
Code:
        <property name="lowestPrice" type="double">
           <formula>
              ( select MIN(s.price) from SKU s where s.productId = id )
           </formula>
        </property>


Yes, if the formula has a select ... from and if the from clause is on the next line i get an SQLGrammar exception. But if I specify the entire select ... from on a single line in my xml file, my formula works great.

I am guessing there is a bug in the formula parser in Hibernate that has a bug. Any comments?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 19, 2005 2:46 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
CDATA?

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 19, 2005 11:03 am 
Beginner
Beginner

Joined: Sun Feb 20, 2005 12:14 am
Posts: 49
Yes.


Top
 Profile  
 
 Post subject: same problem and solution with H303! (formula, column alias)
PostPosted: Fri May 13, 2005 6:15 am 
Newbie

Joined: Thu Jan 08, 2004 11:54 am
Posts: 10
I seem to have had the same problem with Hibernate 3.0.3 - this works:

Code:

<one-to-one name="srcAttr" class="Attribute" >
  <formula>
     (
     select xam.src_attribute_id from xref_attribute_map xam where xam.tgt_attribute_id = Attribute_Id
     and rownum=1
     )
  </formula>
</one-to-one>


ie, it generates the sub-query correctly:
Code:
(
select xam.src_attribute_id from xref_attribute_map xam where xam.tgt_attribute_id = attributes0_.Attribute_Id
and rownum=1
)




but this doesn't:

Code:
<one-to-one name="srcAttr" class="Attribute" >
  <formula>
    (
    select xam.src_attribute_id
    from xref_attribute_map xam where xam.tgt_attribute_id = Attribute_Id
    and rownum=1
    )
   </formula>
</one-to-one>


it produces the following wrong SQL in the subquery:
Code:
(
  select xam.src_attribute_id
  from attributes0_.xref_attribute_map attributes0_.xam where xam.tgt_attribute_id = attributes0_.Attribute_Id
  and rownum=1
)


it has incorrectly prefixed a table alias "attributes0_".

I have seen a few existing references but this thread was the first to provide a solution. Is there something I should do with CDATA?

Thanks
Jeremy.


Top
 Profile  
 
 Post subject: Whitespace possibly fixed
PostPosted: Tue May 24, 2005 1:58 pm 
Newbie

Joined: Tue May 24, 2005 1:52 pm
Posts: 1
I was also running into issues with Hibernate aggressively substituting in table names into my multi-line formula. After I removed the additional whitespace and made the entire query a single line, it started working. I'm hoping that this issue will be resolved in 3.0.5 based on this bug report: http://opensource.atlassian.com/projects/hibernate/browse/HHH-518

-- Daniel R.


Top
 Profile  
 
 Post subject: Thanks!
PostPosted: Wed May 25, 2005 6:21 am 
Newbie

Joined: Thu Jan 08, 2004 11:54 am
Posts: 10
That looks like it,
cheers Daniel.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 14 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.