Forums de discussion

[Solved] HibernateException in 5.1 | How to do Custom SQL Updates in 5.1

Christoph H., modifié il y a 15 années.

[Solved] HibernateException in 5.1 | How to do Custom SQL Updates in 5.1

Regular Member Publications: 147 Date d'inscription: 31/07/07 Publications récentes
Hi,

can someone tell me how to replace the following code in Liferay 5.1?
SessionFactoryImplementor lSF = HibernateUtil.getSessionFactory();
Session session = lSF.openSession();
// Begin Transaction
trans = session.beginTransaction();
// create new RootNode
long nodeId = CounterLocalServiceUtil.increment(Nestedset.class.getName());
node = NestedsetUtil.create(nodeId);
node.setLeftId(1);
node.setRightId(2);
node.setTitle(title);
node.setRootId(nodeId);
// store in DB
session.saveOrUpdate(node);

// set moduls nestedsetid
if (modul != null) {
	modul.setNestedsetId(node.getNestedsetId());
	// save Modul
	session.saveOrUpdate(modul);
}

// flush
session.flush();

trans.commit();


The problem is that HibernateUtil doesn't exist anymore and using only session = openSession() (from BasePersistence) i can't seem to do a session.saveOrUpdate() etc. (method doesn't exist).

Help on this would really be appreciated!
Christoph H., modifié il y a 15 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Regular Member Publications: 147 Date d'inscription: 31/07/07 Publications récentes
Additional Note: This code is inside a CustomNestedsetPersistenceImpl.
Christoph H., modifié il y a 15 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Regular Member Publications: 147 Date d'inscription: 31/07/07 Publications récentes
I think i found a way, but i ran into another problem. When i try this:
Session session = null;
LiferaySession liferaySession = null;
Transaction trans = null;
String sql = null;
SQLQuery q = null;
try {
	_log.debug("In try...");
	// open a new session
	session = openSession();
	SessionImpl sessionImpl = (SessionImpl)session;
	liferaySession = new LiferaySession(sessionImpl.getSession());
...


i get an exception:

An Exception occured: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here


Can anyone tell me how to solve this?
Ed F., modifié il y a 15 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Expert Publications: 280 Date d'inscription: 27/06/06 Publications récentes
Yeah, I got nothin either. If you find out anything please share, I very much need custom SQL queries.

HibernateUtil worked so well.
Christoph H., modifié il y a 15 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Regular Member Publications: 147 Date d'inscription: 31/07/07 Publications récentes
Ed F.:
Yeah, I got nothin either. If you find out anything please share, I very much need custom SQL queries.

HibernateUtil worked so well.


I got it finally running.
Using my code above (the new one without HibernateUtil) you have to create a method with the same Name in the LocalServiceImpl:

So what you have is in Custom*PersistenceImpl:

public Nestedset appendNodeInside(long appendToNodeId, String title)
                        throws SystemException, PortalException {
// custom sql stuff here (see above)
}


and then in NestedsetLocalServiceImpl:

public Nestedset appendNodeInside(long appendToNodeId, String title)
                throws SystemException, PortalException {
                return CustomNestedsetUtil.appendNodeInside(appendToNodeId, title);
        }


Thats basically it. It seems there is *no way* of creating a Hibernate Session outside the XX(Local)Service* classes.
I tried modifying the spring/hibernate configs too, but since those are all autogenerated this doesn't make sense.

I really like to use Springs transaction stuff like unrolling transactions automatically when a specific exception occurs, but this all seems not possible with all this "magically" autogenerated stuff.

HTH
Chris

Unfortunately the Support from Liferay on these topics is very poor. This might sound rude, but i'm quite annoyed by the fact that every LEP Update costs me several days to find out all the things they changed/broke between versions, bc almost nothing is documented and every new version introduces new broken/deleted stuff. For example the struts upload is still broken in 5.1 where it worked all fine in 4.4.2.
Christoph H., modifié il y a 15 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Regular Member Publications: 147 Date d'inscription: 31/07/07 Publications récentes
One additional note: If your caring yourself about transactions etc. make sure not to call your method deleteXX, since this will then conflict with the spring/hibernate config and cause errors. I used removeXX instead.
thumbnail
Ray Augé, modifié il y a 15 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Liferay Legend Publications: 1197 Date d'inscription: 08/02/05 Publications récentes
Hello All,

I think what you are looking for is to have your DAO/Persistence handler extend

[tt]com.liferay.portal.service.persistence.impl.BasePersistenceImpl[/tt]

(this is in the portal-service.jar, so it's reachable from plugins).

But you'll need to initialize the DataSource and the SessionFactory.

The best bet is to take a tour of the sample-service-builder-portlet and basically rip out what you need.

HTH!
thumbnail
Alex Wallace, modifié il y a 15 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Liferay Master Publications: 640 Date d'inscription: 05/11/07 Publications récentes
I'm venturing into a very big upgrade and have many custom queries to upgrade...

I still haven't got to the point where i test the changes, it will be tough to not rewrite the code before i can test...

I hope i'm in the right path... I'm extending BasePersistenceImpl and using it's openSession and other DynamicQuery methods...

So far i'm really missing named parameter substitution, such as:


qry.setLong("paramName", paramValue);


Instead need to use positions...

The other thing I'm missing is how to mark a query as not cacheable... With the hibernate queries I used to be able to do:


sqlQuery.setCacheable(false);


It seems reasonable that liferay wants to be orm independent and hide this functionality... But this is causing lots of upgrade grief...

Is there a document or example with replacements for all the lost methods/functionality?

I looked at the portlet you mention above and while it does show the auto generated code, there are no examples of dynamic queries and sql queries, etc...

I'm flying by instruments, just using code completion and class types to figure my way out, the code seems to be able to compile but again, i will have to rewrite a lot before i can test anything...

Thanks!
thumbnail
Alex Wallace, modifié il y a 15 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Liferay Master Publications: 640 Date d'inscription: 05/11/07 Publications récentes
I have modified some Liferay interfaces and implementations (locally of course) to add named parameters and setParameter w/o having to specify the type to Query and SQLQuery...

I can definitely contribute these to LR... But i need to hear from someone at liferay to know the chances of this making it in the code... I think they were left out because LR is trying to make a true ORM abstraction layer that makes it independent from any particular ORM API...

However, I believe some functionality is must have, and rather than not having some stuff, it should either be implemented, or throw exceptions as not implemented.

I can see liferay is attempting the same about search engines... however I've seen some issues with the current impl that I will post on a separate thread.

I really hope i can get the attention from someone @ liferay (brian? ray?)

Thanks!
thumbnail
Alex Wallace, modifié il y a 15 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Liferay Master Publications: 640 Date d'inscription: 05/11/07 Publications récentes
I am combing through the code to find out where SessionFactory and DataSource are initialized, but haven't found it (still looking)

Any clues as to what file to look at for this?

Thanks!
thumbnail
Alex Wallace, modifié il y a 15 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Liferay Master Publications: 640 Date d'inscription: 05/11/07 Publications récentes
Unable to test yet, i thin i can get the DataSource with InfrastructureUtil.getDataSource() ...

I have not been able to find out how to obtain the Liferay's SessionFactory.. I tried JNDI but no luck...

Any clues?
thumbnail
Alex Wallace, modifié il y a 15 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Liferay Master Publications: 640 Date d'inscription: 05/11/07 Publications récentes
OK!

Finally figured a way... I hope this is 'the right way'

In an empty constcuctor of my Custom Persistence class, which extends BasePersistenceImpl, i do:


        setDataSource(InfrastructureUtil.getDataSource());
        setSessionFactory((SessionFactory)PortalBeanLocatorUtil.getBeanLocator().locate(MyModelImpl.SESSION_FACTORY));


And now my DynamicQueries work...
thumbnail
Alex Wallace, modifié il y a 15 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Liferay Master Publications: 640 Date d'inscription: 05/11/07 Publications récentes
Seems like setSessionFactory is the only necessary piece to this initialization.
thumbnail
Lorenzo Camerini, modifié il y a 14 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

New Member Publications: 6 Date d'inscription: 16/07/09 Publications récentes
Sorry,
I have the same problem, but I can understand what is MyModelImpl.SESSION_FACTORY.
Can you explane better witch name are you passing to the locate method?

Thanks!
thumbnail
Alex Wallace, modifié il y a 14 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Liferay Master Publications: 640 Date d'inscription: 05/11/07 Publications récentes
It's been a long time, but here is how we solved it:

We created a new class which we extend every time we need persistence in say, our Finder classes...

It looks like this:


/**                                                                                                                                                                
 *                                                                                                                                                                 
 * @author aw                                                                                                                                                      
 */
public class MyBasePersistence extends BasePersistenceImpl {

    /** Creates a new instance of MyBasePersistence                                                                                                               
     * Initializes artifacts necessary for connections and                                                                                                         
     * sessions to work                                                                                                                                            
     */
    public MyBasePersistence() {
        setSessionFactory((SessionFactory)PortalBeanLocatorUtil.getBeanLocator().locate(LayoutModelImpl.SESSION_FACTORY));
    }

    public DynamicQuery compileDynamicQuery(DynamicQuery q) {
        Session s = null;
        try {
            s = openSession();
            q.compile(s);
        } finally {
            closeSession(s);
        }
        return q;
    }
...
}


I decided to use LayoutModelImpl.SESSION_FACTORY because a) the name is the same for the portal and b) Layout is one of the first registered beans...

Hope this helps!
We
thumbnail
Lorenzo Camerini, modifié il y a 14 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

New Member Publications: 6 Date d'inscription: 16/07/09 Publications récentes
Hi thank you for your reply,
I am trying to follow your suggestion, but I cannot figure out in which package I can find the LayoutModelImpl.
Probably I didn't import some liferay library in my project, but I cannot find it...
thumbnail
Alex Wallace, modifié il y a 14 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Liferay Master Publications: 640 Date d'inscription: 05/11/07 Publications récentes
In portal source code:

./portal-impl/src/com/liferay/portal/model/impl/LayoutModelImpl.java

find is your friend.
thumbnail
Tim McGuire, modifié il y a 13 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Junior Member Publications: 50 Date d'inscription: 08/01/10 Publications récentes
Lorenzo Camerini:
Hi thank you for your reply,
I am trying to follow your suggestion, but I cannot figure out in which package I can find the LayoutModelImpl.
Probably I didn't import some liferay library in my project, but I cannot find it...


I know this thread is old, but the library you are missing is portal-impl.jar

You can find it in the tomcat bundle ([tomcat_home]\webapps\ROOT\WEB-INF\lib)
thumbnail
Mauro Mariuzzo, modifié il y a 15 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Regular Member Publications: 142 Date d'inscription: 23/07/07 Publications récentes
You are right, there is *no way* of creating a Hibernate Session outside the XX(Local)Service* classes.

But, why are you writing code into *PersistenceImpl?

ServiceBuilder search a file named "persistence/EntityFinderImpl.java".

Here an example:

public class MostVisitedFinderImpl
	extends BasePersistenceImpl implements MostVisitedFinder {

	public int countGroupVisitorsStats(long companyId)
	....
	....
	session = openSession();
	....
	....
 


ServiceBuilder look into *FinderImpl and create MostVisitedFinder.java (the interface). With "*FinderImpl" the "_session" properties inot BasePersistenceImpl in not null.

To use the finder you have to modify the "impl/*(Local)ServiceImpl"


	public int VisitorsStatsCount(long companyId)
		throws SystemException {

		return mostVisitedFinder.countGroupVisitorsStats(companyId);
	}


ServiceBuilder recreate the interfaces so you can use


  MostVistedLocalServiceUtil.VisitorsStatsCount(companyId)


in your java or jsp code
thumbnail
Alex Wallace, modifié il y a 15 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Liferay Master Publications: 640 Date d'inscription: 05/11/07 Publications récentes
Anyone knows what exactly the DynamicQuery compile method is for?
thumbnail
Alex Wallace, modifié il y a 15 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Liferay Master Publications: 640 Date d'inscription: 05/11/07 Publications récentes
I don't see a setDate method on queries either... Is setTimestamp used for that?
thumbnail
Alex Wallace, modifié il y a 15 années.

RE: Need Help: How to replace HibernateUtil in 5.1 | Custom SQL Updates in

Liferay Master Publications: 640 Date d'inscription: 05/11/07 Publications récentes

Does anybody know what the compile method of DynamicQuery is for?


It actually creates the criteria query from which the query is excecuted, so it is indispensable that it is ran..