1

I have an HBM file populated for a table we have. I think created the Java Entity that Hibernate would use. In the Entity, I have the empty constructor and then a full constructor that has all the fields. I put them in the same order as what is in the HBM file as well.

Every time Hibernate uses the Entity, it always calls the empty constructor instead of the full constructor.

Is there a trick or anything that would make Hibernate use the full constructor? This also is happening for all children of the Entity as well. I am running into an issue where my query.list() is running slow and want to get this to work to see if it will speed things up.

Thank you!

Note: I did not include the contents of the HBM and Java file because (a) it contains company information and (b) it is rather large. It would take a very long time to strip things out. I am sorry if this is inconvenient :(

Ascalonian
  • 14,409
  • 18
  • 71
  • 103
  • 1
    If down voting, please tell me why so I can adjust the question. – Ascalonian Jul 17 '14 at 16:03
  • As far as I know, Hibernate won't call the "full" constructor. It will call your no-arg constructor and will do a field or property (getter/setter) call depending on how you set it up. Have you checked the Hibernate documentation? [2.2. The entity Java class](https://docs.jboss.org/hibernate/core/4.3/quickstart/en-US/html_single/#hibernate-gsg-tutorial-basic-entity) – Roy Six Jul 17 '14 at 16:18
  • I downvoted (which I have never done before, btw) because if you do a search on this topic, you'll find lots of hits that explain how hibernate calls constructors. I'll remove the downvote (if the system will allow me), but it seemed like you didn't do a search before posting your question. If I'm wrong, I apologize. But in any case, hibernate will call the default/no-args constructor. – Steve Harrington Jul 17 '14 at 16:38
  • I did do a search. One of the posts (from here) mentioned that they created a full constructor and it resolved the issue. So I went ahead and tried it but for every way I tried, it won't call the full constructor instead of the no-arg constructor. – Ascalonian Jul 17 '14 at 17:51
  • The post :-) - http://stackoverflow.com/questions/6609645/simple-hibernate-query-returning-very-slowly – Ascalonian Jul 17 '14 at 17:57
  • Hibernate requires a no-args constructor as described [here](https://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/persistent-classes.html#persistent-classes-pojo-constructor), but there may be some other ways -- e.g. with an interceptor? -- to call a non-default constructor. Apologies; I tried to remove the downvote, but could not. – Steve Harrington Jul 17 '14 at 18:13
  • Oh, I understand that the no-arg constructor is required. Just trying to make it not be called. I think I have a solution will have to wait until tomorrow to test. – Ascalonian Jul 17 '14 at 21:27
  • Can you explain more about why you don't want the default constructor called? – Jeff Aug 04 '14 at 18:47

3 Answers3

5

There are 3 strategies for instantiating objects through Hibernate (that I know of).

Standard method

HQL or criteria queries like select from cat will create POJOs (here, instances of Cat - or subclasses), and Hibernate will do so by calling the no-arg constructor. From documentation :

All persistent classes must have a default constructor (which can be non-public) so that Hibernate can instantiate them using java.lang.reflect.Constructor.newInstance(). It is recommended that this constructor be defined with at least package visibility in order for runtime proxy generation to work properly.

Choosing a Constructor with HQL

One can reference a specific constructor to invoke through a specially crafted select statement in a HQL query.
E.g. select new com.example.Cat(cat.id, cat.name) from Cat works. If your request is correctly defined, you can also use functions such as count() in your select. This would call a 2 arguments contructor on Cat - although I do not think this will automatically adjust to find another class that Cat in case of polymorphism.

You can explore various possibilities (e.g. how to build a list) in the documentation : http://docs.jboss.org/hibernate/core/3.3/reference/en/html/queryhql.html#queryhql-select

Using a result transformer

The concept of ResultTransformer allows you to specify, on a Criteria objet, how results will be transformed to objects. Using an AliasToBeanConstructorResultTransformer, which takes a java.lang.Constructor as an argument, you can choose the constructor being called. (By default, every criteria has a ResultTransformer which is RootEntityResultTransformer).

GPI
  • 9,088
  • 2
  • 31
  • 38
1

Are you working with really large resultsets? What repository are you using? I've encountered similar issues and it came down to database settings for hibernate.

Here are a few other questions to check out:

Simple hibernate query returning very slowly

Hibernate queries slow down drastically after an entity is loaded in the session

For hibernate, I've found the following settings you may tweak to improve performance. :

        // update - Create if schema doesn't exists; update if column doesn't
    // exist
    // create - Empties the database before creating it
    // create-drop - Drops the database when the SessionFactory is closed
    config.setProperty("hibernate.hbm2ddl.auto", hbm2ddlMode);
    config.setProperty("hibernate.cache.use_query_cache", "true");
    config.setProperty("hibernate.cache.use_second_level_cache", "true");
    config.setProperty("hibernate.cache.region.factory_class",
        "org.hibernate.cache.ehcache.EhCacheRegionFactory");
    config.setProperty("hibernate.cache.provider_class",
        "org.hibernate.cache.EhCacheProvider");
    // config.setProperty("hibernate.cache.provider_class",
    // "org.hibernate.cache.NoCacheProvider");
    config.setProperty("hibernate.jdbc.fetch_size", "1000");
    config.setProperty("hibernate.jdbc.batch_size", "50"); //batches network calls in one
    config.setProperty("hibernate.jdbc.use_scrollable_resultset", "true");

    config.setProperty("hibernate.connection.provider_class",
        "org.hibernate.connection.C3P0ConnectionProvider");
    config.setProperty("hibernate.c3p0.acquire_increment", "1");
    config.setProperty("hibernate.c3p0.idle_test_period", "10");
    config.setProperty("hibernate.c3p0.min_size", "1");
    config.setProperty("hibernate.c3p0.max_size", "8");
    config.setProperty("hibernate.c3p0.timeout", "10");
    config.setProperty("javax.persistence.validation.mode", "none");
    config
        .setProperty("hibernate.temp.use_jdbc_metadata_defaults", "false");
    config.setProperty("hibernate.show_sql", "false");

Note, these specific settings may not be ideal for your database, but you should be able to improve performance by tweaking the properties above. Detailed explanation can be found on the doc site.

For sqlite, you have to tweak a few additional settings:

        config.setPageSize(4096);
    config.setCacheSize(-256);

    config.setSharedCache(true);
    config.setReadUncommited(true);

    //Be careful with these settings if needed for concurrency
    //***************************************************
    config.setLockingMode(LockingMode.NORMAL);
    config.setSynchronous(SynchronousMode.NORMAL);
    config.setJournalMode(JournalMode.WAL);
    config.setTempStore(TempStore.MEMORY);
    //***************************************************

Postgres is a bit simpler and more isolated to the database settings itself. However, keep in mind the query optimizer kicks in after the first query run.

Community
  • 1
  • 1
Jason Huntley
  • 3,827
  • 2
  • 20
  • 27
0

After some research I found this useful

An hibernate entity must define a no argument constructor. Hibernate creates new instances of entities through reflection, with the Class.newInstance() method. This method requires a no argument constructor to succeed. If an entity does not provide a no argument constructor, an Hibernate’s InstantiationException will be thrown.

Check here

deejay
  • 575
  • 1
  • 8
  • 24