<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Anne Epstein : Caching</title><link>http://devlicio.us/blogs/anne_epstein/archive/tags/Caching/default.aspx</link><description>Tags: Caching</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>NHibernate Caching and Assigned Ids - A Potential Pitfall</title><link>http://devlicio.us/blogs/anne_epstein/archive/2009/10/08/nhibernate-caching-and-assigned-ids-a-potential-pitfall.aspx</link><pubDate>Thu, 08 Oct 2009 13:53:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:52457</guid><dc:creator>Anne Epstein</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/anne_epstein/rsscomments.aspx?PostID=52457</wfw:commentRss><comments>http://devlicio.us/blogs/anne_epstein/archive/2009/10/08/nhibernate-caching-and-assigned-ids-a-potential-pitfall.aspx#comments</comments><description>&lt;p&gt;Yesterday, I spent some time setting up and optimizing SysCache2 caching.&amp;nbsp; (By the way, if you&amp;#39;re doing this kind of NHibernate tuning, NHProf - a devlicio.us friend - is crucial, it would have definitely been a much tougher slog without it) With caching turned on, one of our previously well-functioning classes was consistently giving the following error EVERY time we tried to modify and save an instance: &lt;/p&gt;
&lt;p&gt;ReadOnlyCache: Can&amp;#39;t write to a readonly object&lt;/p&gt;
&lt;p&gt;Looking this up, I ran across a LOT of information about how this meant the cache line in the mapping was wrong - that it needed to be marked read-write, not read-only.&amp;nbsp; The odd thing was, this is what the cache line in our mapping was like already:&lt;/p&gt;
&lt;p&gt;&amp;lt;cache usage=&amp;quot;read-write&amp;quot; region=&amp;quot;SomeRegion&amp;quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;So, our problem was NOT the obvious issue that our object was improperly marked as readonly.&amp;nbsp; But... after a lot of flailing around, the solution emerged.&amp;nbsp; Check out this definition of the ID on this entity:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;id name=&amp;quot;Id&amp;quot; column=&amp;quot;EntityID&amp;quot; type=&amp;quot;Int32&amp;quot; unsaved-value = &amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;generator class=&amp;quot;assigned&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/id&amp;gt;&lt;/p&gt;
&lt;p&gt;Note the use of &amp;quot;assigned&amp;quot; for the id generator.&amp;nbsp; It means NHibernate doesn&amp;#39;t control the id-it&amp;#39;s manually managed. Now if you&amp;#39;re familiar with the assigned generator, you know that it&amp;#39;s a somewhat troublesome thing to work with-specifically, if you call SaveOrUpdate on an entity using it, NHibernate won&amp;#39;t know whether it&amp;#39;s a new entity or not on its own, because NHibernate tracks the state of the entiy using the id.&amp;nbsp; This affects cascade saves as well, so assigned ids aren&amp;#39;t fun. If you take over managing that id yourself, NHibernate doesn&amp;#39;t have anything to hang its tracking off of.&amp;nbsp; Assigned ids are something you should probably avoid for new applications, but&amp;nbsp; sometimes that&amp;#39;s not an option&amp;nbsp; for legacy apps.... If you NEED to use an assigned id there&amp;#39;s an easy way to get this entity acting like a normal NHibernate entity-you can give NHibernate something to use like this: &lt;/p&gt;
&lt;p&gt;&amp;lt;version name=&amp;quot;LastModifiedOn&amp;quot; type=&amp;quot;timestamp&amp;quot; column=&amp;quot;LastModifiedOn&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp; /&amp;gt;&lt;br /&gt;-with the matching column, and the matching property in the class - or maybe even just using the access=&amp;quot;field..&amp;quot; option in the mapping so it&amp;#39;s not mistakenly taken to be something to be part of the class&amp;#39;s regular api by another programmer-this field is NOT FOR YOU, it&amp;#39;s for NHibernate. Look at it if you want, but do not touch! Note that if you add a column like this to an existing table, you&amp;#39;re going to have to prepopulate the existing rows for your your new column with an initial datetime or you&amp;#39;ll get errors-any date at all, so long as it&amp;#39;s in the past. 1/1/2009 12:00:00 is as good a value as any.... &lt;/p&gt;
&lt;p&gt;What does this have to do with my caching problem?&amp;nbsp; The particular entity I was getting the erroneous readonly caching&amp;nbsp; problems on didn&amp;#39;t have the &amp;lt;version&amp;gt; property-a bad state of things for an assigned id entity.&amp;nbsp; Oddly, it *was* in fact saving properly using SaveOrUpdate - perhaps it was the  unsaved-value = &amp;quot;0&amp;quot; on the id allowing it to work, maybe not.&amp;nbsp; Anyway, the solution ended up being adding a &amp;lt;version&amp;gt; property and column, and then it worked like a charm. I probably should have caught that this entity was missing &amp;lt;version&amp;gt; earlier, but it seemed to work ok, and the potential problem stayed hidden until the entity got thrown into the cache.&lt;/p&gt;
&lt;p&gt;By the way, if you don&amp;#39;t like&amp;nbsp; &amp;lt;version&amp;gt;, there are alternatives, like &lt;tt class="literal"&gt;&lt;a href="http://www.nhforge.org/doc/nh/en/index.html#example-parentchild-update"&gt;IInterceptor.IsTransient() &lt;/a&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=52457" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/anne_epstein/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/anne_epstein/archive/tags/Caching/default.aspx">Caching</category></item></channel></rss>