Ascalonian
Ascalonian

Reputation: 15174

Hibernate: Why isn't the full constructor being called?

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 :(

Upvotes: 1

Views: 3005

Answers (3)

deejay
deejay

Reputation: 575

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

Upvotes: 0

GPI
GPI

Reputation: 9328

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).

Upvotes: 5

Jason Huntley
Jason Huntley

Reputation: 3877

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.

Upvotes: 1

Related Questions