• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Ron McLeod
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Junilu Lacar
  • Tim Cooke
Saloon Keepers:
  • Carey Brown
  • Stephan van Hulst
  • Tim Holloway
  • Peter Rooke
  • Himai Minh
Bartenders:
  • Piet Souris
  • Mikalai Zaikin

@Generated values

 
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Confidence in these annotations have waned a bit as it turns out that apparently at least some of them aren't actually paid attention by Hibernate anyway - so as it doesn't appear to working as the book says, I'll ask here to see if this is another ignored @annotation or if I'm actually doing it wrong.

I have the following @Generated attribute on a class :-



The value in there is provided by the SQL database not the app which is using Hibernate. Though it isn't something like a primary key, and it isn't set by the SQL DB itself but by another application working elsewhere, it is essentially a DB generated value which every so often needs to be loaded into memory - without an inordinate number of database hits, as there could be a lot of these.

Every minute that value needs to be reread from the SQL and loaded into the objects in memory (held in a List<Sensor>). And here is where it all falls down.

1) Session.refresh() creates one database hit per sensor - that takes far too long, even given that this is threaded, so can't be used - besides, its wild inefficiency for something so easy is irksome.

2) I tried detaching all the sensor objects from the persistence context, flushing everything, reading a brand new (and separate) List of sensors so they are back in the persistence context, and then reattaching the old sensor references with persist. This doesn't seem to work as despite the @Generated tag Hibernate seems to want to always use the values in memory (which are now stale) over the updated generated values in the database despite the generated tag (and despite that they are set read only!).



I'm pondering just setting the sensor value to a transient field and just doing it all myself without Hibernate involved at all - just do all the refreshing stuff personally. But that does seem a bit silly given thats why Hibernate is supposed to be doing for me.

I've not seen very much in the documentation or on the web regarding getting data attributes from database to app rather than from app to database. Is session.refresh() really the only option Hibernate presents here?
 
Bartender
Posts: 10336
Hibernate Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Confidence in these annotations have waned a bit as it turns out that apparently at least some of them aren't actually paid attention by Hibernate anyway - so as it doesn't appear to working as the book says, I'll ask here to see if this is another ignored @annotation or if I'm actually doing it wrong


Well to be fair to Hibernate, the only annotations or mappings that are ignored are those that could contradict or undermine the fetch strategy defined in your HQL. Either the annotations had to be ignored or part of the HQL had to be ignored, you can't have both honoured. I'll not defend how well documented this is however.

In your previous post you had wrapped your read in a transaction. Are you flushing the session etc. in that same transaction?
 
Robert Fry
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Sturrock wrote:
Well to be fair to Hibernate, the only annotations or mappings that are ignored are those that could contradict or undermine the fetch strategy defined in your HQL. Either the annotations had to be ignored or part of the HQL had to be ignored, you can't have both honoured. I'll not defend how well documented this is however.



OK.


In your previous post you had wrapped your read in a transaction. Are you flushing the session etc. in that same transaction?



I've actually followed some advice and took most of the transactions out.

The last bunch of attempts were all variants on something like this



with a few changes. s.refresh, s.persist, s.merge, I've tried a lot of things.

But thats essentially the 'detach, reload all of them in one query, try to reattach' idea I was trying.
 
Paul Sturrock
Bartender
Posts: 10336
Hibernate Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


I've actually followed some advice and took most of the transactions out.


Transactions for reads are unnecessary. Transactions for data manipulation are mandatory. The only (sort of) exception to this is unless you are running in auto commit mode, which be default you are not. Using auto commit you are using transaction implicitly.

Generation (of any kind) in Hibernate only happens when you perform an insert or update. If you are not running in a transaction, the generation stuff will never commit.
 
Robert Fry
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Sturrock wrote:


I've actually followed some advice and took most of the transactions out.


Transactions for reads are unnecessary. Transactions for data manipulation are mandatory. The only (sort of) exception to this is unless you are running in auto commit mode, which be default you are not. Using auto commit you are using transaction implicitly.

Generation (of any kind) in Hibernate only happens when you perform an insert or update. If you are not running in a transaction, the generation stuff will never commit.



Right, OK. This is what I was running. Two transactions just for my own peace of mind.



The things I learned from this are

a) the evict() command really does work, the sensors are most definitely detached. (discovered with some attempts to save those objects without reattaching them)
b) the cache seems to keep its hands on the sensor objects despite the evict. The intermediate list, newsensorlist, has the same values as the original sensorlist, so it's already out of kilter with the database at that point - so the merging bit later on is irrelevant.
c) Yet despite this, show_sql being true does reveal that there is indeed a single SQL SELECT query being sent to the database.

Not that the numbers mean much but this is the output this generates (the numbers in the SQL database have indeed changed over the course of this refresh, so if it was working at least some of the 'read from DB' values should be different).

Old value : 12.324219
Old value : 66.11719
Old value : 18.1
Old value : 42.0
Old value : 21.2
Old value : 51.0
Old value : 21.042969
Old value : 51.36328
Old value : 0.0
Hibernate: select this_.Sensor_ID as Sensor1_4_6_, this_.Sensor_AlmHi as Sensor2_4_6_, this_.Sensor_AlmLo as Sensor3_4_6_, this_.Sensor_PncHi as Sensor4_4_6_, this_.Sensor_PncLo as Sensor5_4_6_, this_.TX_ID as TX7_4_6_, this_.SType_ID as SType8_4_6_, this_.Sensor_LastValue as Sensor6_4_6_, transmitte2_.TX_ID as TX1_5_0_, transmitte2_.TX_STATUS1 as TX2_5_0_, transmitte2_.TX_LASTRECD as TX3_5_0_, transmitte2_.TX_LATEAFTER as TX4_5_0_, transmitte2_.TX_LOCATION as TX5_5_0_, transmitte2_.RX_ID as RX7_5_0_, transmitte2_.TX_ADDRESS as TX6_5_0_, transmitte2_.TXTYPE_ID as TXTYPE8_5_0_, receiver3_.RX_ID as RX1_6_1_, receiver3_.RX_NAME as RX2_6_1_, transmitte4_.TXTYPE_ID as TXTYPE1_0_2_, transmitte4_.TXTYPE_NAME as TXTYPE2_0_2_, transmitte5_.TX_PLANPLACE_ID as TX1_7_3_, transmitte5_.FLOOR_ID as FLOOR5_7_3_, transmitte5_.TX_PLANPLACE_ORIGINAL_SIZE as TX2_7_3_, transmitte5_.TX_ID as TX6_7_3_, transmitte5_.TX_PLANPLACE_X as TX3_7_3_, transmitte5_.TX_PLANPLACE_Y as TX4_7_3_, floor6_.FLOOR_ID as FLOOR1_3_4_, floor6_.BUILDING_ID as BUILDING2_3_4_, floor6_.FLOOR_TREEINDEX as FLOOR3_3_4_, floor6_.FLOOR_IMAGE_SOURCE as FLOOR4_3_4_, floor6_.FLOOR_NAME as FLOOR5_3_4_, floor6_.FLOOR_ORIGIN_X as FLOOR6_3_4_, floor6_.FLOOR_ORIGIN_Y as FLOOR7_3_4_, floor6_.FLOOR_SCALE_MULTIPLIER as FLOOR8_3_4_, sensortype7_.STYPE_ID as STYPE1_1_5_, sensortype7_.SType_EU as SType2_1_5_, sensortype7_.SType_Format as SType3_1_5_, sensortype7_.SType_MaxValue as SType4_1_5_, sensortype7_.SType_MinValue as SType5_1_5_, sensortype7_.SType_Type as SType6_1_5_ from Sensor this_ left outer join TX transmitte2_ on this_.TX_ID=transmitte2_.TX_ID left outer join RX receiver3_ on transmitte2_.RX_ID=receiver3_.RX_ID left outer join TX_TYPE transmitte4_ on transmitte2_.TXTYPE_ID=transmitte4_.TXTYPE_ID left outer join TX_PLANPLACE transmitte5_ on transmitte2_.TX_ID=transmitte5_.TX_ID left outer join FLOOR floor6_ on transmitte5_.FLOOR_ID=floor6_.FLOOR_ID left outer join Sensor_Type sensortype7_ on this_.SType_ID=sensortype7_.STYPE_ID
DB read value : 12.324219
DB read value : 66.11719
DB read value : 18.1
DB read value : 42.0
DB read value : 21.2
DB read value : 51.0
DB read value : 21.042969
DB read value : 51.36328
DB read value : 0.0
Merged value 12.324219
Merged value 66.11719
Merged value 18.1
Merged value 42.0
Merged value 21.2
Merged value 51.0
Merged value 21.042969
Merged value 51.36328
Merged value 0.0

 
Robert Fry
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Aha, something has happened. I fiddled some more (more flush()) and now I see :-

Old value : 12.324219
Old value : 66.45703
Old value : 18.1
Old value : 42.0
Old value : 21.2
Old value : 51.0
Old value : 21.152344
Old value : 51.36328
Old value : 0.0
DB read value : 12.324219
DB read value : 66.359375
DB read value : 18.1
DB read value : 42.0
DB read value : 21.2
DB read value : 51.0
DB read value : 21.152344
DB read value : 51.36328
DB read value : 0.0
Merged value 12.324219
Merged value 66.45703
Merged value 18.1
Merged value 42.0
Merged value 21.2
Merged value 51.0
Merged value 21.152344
Merged value 51.36328
Merged value 0.0

So it's read in the different value finally. Though merge() clearly isn't the method I want to use to reattach...
 
Robert Fry
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Alright, defeated!

The Easy Way.

 
reply
    Bookmark Topic Watch Topic
  • New Topic