|
View:
New views
8 Messages
—
Rating Filter:
Alert me
|
|
|
Inserts and CachingHi,
I have the following design problem. I have in EJB a remote interface which actually is a projection of my use-case. This remote method calls different local apis. Important to know is that the use-case is a unit. Or the method is committed or rolled back completely. Now, during the execution of this method I have a call to a method which insert event-objects into the database. Unfortunately, these event objects remain in memory until my transaction commits. Is there a way to avoid this (without having to use the SQL INSERT statement directly)? I found in EclipseLink the method InsertObjectQuery. public void sendEvent(NodeEntity nodeEntity, EventType eventType) { EventEntity event = new EventEntity(); event.setNodeGuid(.....); event.setEventType(....); /* This is the EclipseLink specific part */ InsertObjectQuery writeQuery = new InsertObjectQuery(); writeQuery.setObject(event); writeQuery.dontMaintainCache(); /* Convert the query to JPA query */ Query q = JpaHelper.createQuery(writeQuery, this.getEntityManager()); q.executeUpdate(); } This method, I hope, should be able NOT TO CACHE the EventEntity? So, when I have let's say 5000 eventEntities in my method, they will not remain in memory and will not cause a heap space problem? Unfortunately, this method does not function within JPA (Glassfish). I get the following error: Objects cannot be written during a UnitOfWork, they must be registered. I tried to register it (using entitymanager.getUnitOfWork().registerNewObject() etc), but without success. Are my assumptions correct and/or is there a method to do insert using the API in JPA (so I can refactor it easily) ? Now, as a work-around I use the SQL INSERT statement directly, but that is not always portable. Actually, I would be nice if you could remove one object from the cache or to prevent the object from being cached. Sometimes, you have objects you must write to the database use JPA (annotated with @PrePersist etc) which you don't need afterwards. Does the annotations @Cache(type=CacheType.NONE) actually function when I execute the normal "entitymanager.persist(eventEntity)"? Greetings Jan |
|
|
Re: Inserts and CachingAnyone?
Thanks Jan |
|
|
Re: Inserts and CachingAre you concerned with caching across transaction or within the same transaction?
Across transaction you can disable caching using the persistence.xml property, "eclipselink.cache.shared.default"="false". Or you can set the size or type of the cache to control how many objects are cached. For avoiding caching within a single transaction, the best way is to flush() then clear() the EntityManager. You could do this for each object, or probably better for each batch of objects. Also ensure you application does not hold onto the objects, otherwise they will not be able to gc.
James Sutherland EclipseLink, TopLink Wiki: EclipseLink, TopLink Forums: TopLink, EclipseLink Book: Java Persistence |
|
|
Re: Inserts and CachingThanks for the follow-up.
It is the caching within the same transaction. Let's say in one transaction I have to persist 5000 objects which I do not need afterwards. They should not unnecessary remain in memory. When a couple of requests are running, then the memory is filled up pretty quickly. Does the @Cache NONE actually helps? I wasn't able to find out if the object was cached. Thanks for the tip. Ok, but then the transaction is committed and restarted. In case of a rollback I have "unstable" data since the part before the flush wasn't rolled back. Thanks Jan |
|
|
Re: Inserts and Caching> Does the @Cache NONE actually helps? I wasn't able to find out if the object was cached.
No do not use NONE, to disable the shared cache use shared=false. NONE should generally only be used for simple objects without relationships. > Ok, but then the transaction is committed and restarted. In case of a rollback I have "unstable" data since the part before the flush wasn't rolled back. No flush() does not commit the transaction, only commit() commits the transaction, flush() just writes the SQL to the database, rollback will still rollback everything from the point of the begin().
James Sutherland EclipseLink, TopLink Wiki: EclipseLink, TopLink Forums: TopLink, EclipseLink Book: Java Persistence |
|
|
Re: Inserts and CachingOk, but does a flush clear the cache? I.e. will the object up to this point be garbage collected? Thanks Jan |
|
|
Re: Inserts and CachingAnyway, I still have the problem why the Insert over the API does not work....
Can somebody help? Thanks Jan |
|
|
Re: Inserts and CachingJan,
Assuming that these operations occur within a single JTA or application managed transaction you should use the following pattern. ->begin operations - transaction alpha active<- //operate on em while (?){ em.persist(); // or whatever else needs to happen } //operation complete em.flush(); // flush changes to database within current transaction em.clear(); //clear the em (including em cache) of all managed entities (you may not always need this) ->end operation - transaction alpha still active <- as long as the same transaction is active for all of the operations if anything fails a rollback of the transaction will revert all of the SQL EclipseLink sent to the database within that transaction from all of the previous flush operations. On rollback the EntityManager will be cleared and your application will have a clean slate. The old entities that were previously associated with this EM will now be detached and are in a state where they may have uncommitted changes. Some applications can use these detached instances to retry the transaction with EM.merge() other applications will throw them away and start from scratch. --Gordon ossaert wrote: > Anyway, I still have the problem why the Insert over the API does not > work.... > > Can somebody help? > > Thanks > Jan > > > eclipselink-users mailing list eclipselink-users@... https://dev.eclipse.org/mailman/listinfo/eclipselink-users |
| Free embeddable forum powered by Nabble | Forum Help |