<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<base href="https://hibernate.atlassian.net">
<title>Message Title</title>
</head>
<body class="jira" style="color: #333333; font-family: Arial, sans-serif; font-size: 14px; line-height: 1.429">
<table id="background-table" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0; mso-table-rspace: 0; background-color: #f5f5f5; border-collapse: collapse; mso-table-lspace: 0; mso-table-rspace: 0" bgcolor="#f5f5f5">
<!-- header here -->
<tbody>
<tr>
<td id="header-pattern-container" style="padding: 0; border-collapse: collapse; padding: 10px 20px">
<table id="header-pattern" cellspacing="0" cellpadding="0" border="0" style="border-collapse: collapse; mso-table-lspace: 0; mso-table-rspace: 0">
<tbody>
<tr>
<td id="header-avatar-image-container" valign="top" style="padding: 0; border-collapse: collapse; vertical-align: top; width: 32px; padding-right: 8px" width="32"> <img id="header-avatar-image" class="image_fix" src="https://secure.gravatar.com/avatar/df12d7792bd3b7be3a4edf12cabd58cb?d=mm&s=48" height="32" width="32" border="0" style="border-radius: 3px; vertical-align: top"> </td>
<td id="header-text-container" valign="middle" style="padding: 0; border-collapse: collapse; vertical-align: middle; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px"> <a class="user-hover" rel="steve" id="email_steve" href="https://hibernate.atlassian.net/secure/ViewProfile.jspa?name=steve" style="color:#6c797f;; color: #3b73af; text-decoration: none">Steve Ebersole</a> <strong>commented</strong> on <a href="https://hibernate.atlassian.net/browse/HHH-11356" style="color: #3b73af; text-decoration: none"><img src="cid:jira-generated-image-avatar-29b69c32-8563-4f13-becb-df227ea5dd73" height="16" width="16" border="0" align="absmiddle" alt="Improvement"> HHH-11356</a> </td>
</tr>
</tbody>
</table> </td>
</tr>
<tr>
<td id="email-content-container" style="padding: 0; border-collapse: collapse; padding: 0 20px">
<table id="email-content-table" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0; mso-table-rspace: 0; border-spacing: 0; border-collapse: separate">
<tbody>
<tr>
<!-- there needs to be content in the cell for it to render in some clients -->
<td class="email-content-rounded-top mobile-expand" style="padding: 0; border-collapse: collapse; color: #ffffff; padding: 0 15px 0 16px; height: 15px; background-color: #ffffff; border-left: 1px solid #cccccc; border-top: 1px solid #cccccc; border-right: 1px solid #cccccc; border-bottom: 0; border-top-right-radius: 5px; border-top-left-radius: 5px; height: 10px; line-height: 10px; padding: 0 15px 0 16px; mso-line-height-rule: exactly" height="10" bgcolor="#ffffff"> </td>
</tr>
<tr>
<td class="email-content-main mobile-expand " style="padding: 0; border-collapse: collapse; border-left: 1px solid #cccccc; border-right: 1px solid #cccccc; border-top: 0; border-bottom: 0; padding: 0 15px 0 16px; background-color: #ffffff" bgcolor="#ffffff">
<table class="page-title-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0; mso-table-rspace: 0">
<tbody>
<tr>
<td style="vertical-align: top;; padding: 0; border-collapse: collapse; padding-right: 5px; font-size: 20px; line-height: 30px; mso-line-height-rule: exactly" class="page-title-pattern-header-container"> <span class="page-title-pattern-header" style="font-family: Arial, sans-serif; padding: 0; font-size: 20px; line-height: 30px; mso-text-raise: 2px; mso-line-height-rule: exactly; vertical-align: middle"> <a href="https://hibernate.atlassian.net/browse/HHH-11356" style="color: #3b73af; text-decoration: none">Re: Adjust the 2nd-Cache SPIs to better reflect supported uses</a> </span> </td>
</tr>
</tbody>
</table> </td>
</tr>
<tr>
<td id="text-paragraph-pattern-top" class="email-content-main mobile-expand comment-top-pattern" style="padding: 0; border-collapse: collapse; border-left: 1px solid #cccccc; border-right: 1px solid #cccccc; border-top: 0; border-bottom: 0; padding: 0 15px 0 16px; background-color: #ffffff; border-bottom: none; padding-bottom: 0" bgcolor="#ffffff">
<table class="text-paragraph-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0; mso-table-rspace: 0; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 2px">
<tbody>
<tr>
<td class="text-paragraph-pattern-container mobile-resize-text " style="padding: 0; border-collapse: collapse; padding: 0 0 10px"> <p style="margin: 10px 0 0; margin-top: 0">I'll answer your questions in a different order than you asked them as each answer I think builds upon the other...</p>
<blockquote style="margin: 10px 0 0; border-left: 1px solid #cccccc; color: #707070; margin-left: 19px; padding: 10px 20px">
<p style="margin: 10px 0 0; margin-top: 0">Then, what does "buildRegion" mean? Since you expect it to return such an empty shell, why do we need that Region instance at all?</p>
</blockquote> <p style="margin: 10px 0 0">Well as we discussed on phone, there are many places where Hibernate exposes operations/information on a per-Region (name) basis (statistics, eviction, etc). Obviously having a singular object that a region name points to helps with that. Again, Region is a Hibernate-specific concept. I cannot say that any more clearly <img class="emoticon" src="cid:jira-generated-image-static-wink-dc46f6a4-dca8-4a02-8ac0-b6fcfa7dd769" height="16" width="16" align="absmiddle" alt="" border="0"></p>
<blockquote style="margin: 10px 0 0; border-left: 1px solid #cccccc; color: #707070; margin-left: 19px; padding: 10px 20px">
<p style="margin: 10px 0 0; margin-top: 0">I am making an assumption that Region maps to a shared map-like data storage. Is that too much? </p>
</blockquote> <p style="margin: 10px 0 0">Yes, that is too much. Region, at the end of the day, is a Hibernate specific concept for the express purposes listed above. What else each provide bakes into its Region impl is up to that provider. I would expect that means whatever is needed to build RegionAccess objects - which again is going to be provider-specific.</p> <p style="margin: 10px 0 0">As we discussed on that phone call we had, I'd fully expect the combination of <tt>(region-name, role, accessType)</tt> to be the "unique key" referring to a particular provider's cache object (an Infinispan <tt>org.infinispan.Cache</tt> e.g.). Really the accessType is superfluous in terms of making the key here unique. <tt>(region-name, role)</tt> is unique by itself - a given "role" can only specify a single AccessType.</p> <p style="margin: 10px 0 0">And again, you have all that info by the time you are asked to build a RegionAccess. Call it CachedDataAccess if you like that name better. Regardless of the name, the intent is that it provides access to the specific kind of data indicated (entity, collection, natural-id) in the indicated named-region using the indicated AccessType.</p>
<blockquote style="margin: 10px 0 0; border-left: 1px solid #cccccc; color: #707070; margin-left: 19px; padding: 10px 20px">
<p style="margin: 10px 0 0; margin-top: 0">All instance of RegionAccess coming from the same region will keep references to the same components, therefore there's no state per RegionAccess. But this is a bit of digression, and speaks about the current implementation - but do you expect these objects to keep any state?</p>
</blockquote> <p style="margin: 10px 0 0">I'd expect it to keep a reference to the underlying cache that it is providing access to. Again that is not the same as Region. Also again, for Infinispan e.g. this would be a <tt>org.infinispan.Cache</tt> as I understand it.</p>
<blockquote style="margin: 10px 0 0; border-left: 1px solid #cccccc; color: #707070; margin-left: 19px; padding: 10px 20px">
<p style="margin: 10px 0 0; margin-top: 0">But my problem is that I don't have all this info when someone calls buildEntityRegionAccess because I don't know if someone will call that method again with different arguments in the next second. I have to either use the most generic implementation, or optimistically assume that there won't be a second call and if there is such invocation with incompatible arguments, throw an exception (or do a complicated fallback to the generic implementation).</p>
</blockquote> <p style="margin: 10px 0 0">I really have no idea what you are getting at when you say "I don't know if someone will call that method again with different arguments in the next second". That method will get called multiple times. And 80% of the time the difference in arguments is completely irrelevant for what you elsewhere state is what you want to achieve.</p> <p style="margin: 10px 0 0">Really (I think) it boils down to you want to know ahead of time how many CacheDataDescriptions we will be storing in that Region. E.g. if we will be storing Person entity data and Company entity data in the same region - that is important information to you so you can pick the proper CacheKeyFactory to use e.g. Again, for any given CacheDataDescription (Person, Company) the AccessType will always be the same.</p> <p style="margin: 10px 0 0">What you want to additionally enforce is for a Region to only be able to host a single AccessType. I am not going to make that a baked-in restriction, unless everyone here agrees that that should be a restriction across all providers. But personally I think that really just shows a mis-understanding of Region and RegionAccess and how to implement them.</p>
<blockquote style="margin: 10px 0 0; border-left: 1px solid #cccccc; color: #707070; margin-left: 19px; padding: 10px 20px">
<p style="margin: 10px 0 0; margin-top: 0">Regarding the wish list: I had no particular format in mind, I meant just "all data", though I've assumed something like the (Entity)CacheDataDescriptions. Something implementation could use to turn some optimizations if the data is immutable, if we store just single type and so on.</p>
</blockquote> <p style="margin: 10px 0 0">Handing the Region its CacheDataDescriptions up-front introduces a chicken-egg. The CacheDataDescription is, e.g., the EntityPersister and CollectionPersister which is also the thing that need the RegionAccess during it initialization. We had decided to make the persisters the CacheDataDescription impls mainly to save instantiations. It is possibly I guess that we could implement CacheDataDescription separate from the persisters and create those for each call to get a UserModelRegionAccess. Resolving the UserModelRegionAccess only happens once per CacheDataDescription, at SessionFactory bootstrap. So even though this approach would cause an additional instantiation per persister creation, it would be limited to just bootstrap. Still I tend to prefer to avoid unnecessary object instantiations - and your group does as well <img class="emoticon" src="cid:jira-generated-image-static-wink-dc46f6a4-dca8-4a02-8ac0-b6fcfa7dd769" height="16" width="16" align="absmiddle" alt="" border="0"></p>
<hr> <p style="margin: 10px 0 0">All told, let's step back and look at an example, which I think might help. Let's imagine we have a finctional cache library called Cacheaholic that we want to integrate with Hibernate via RegionFactory. Cacheaholic's main cache contract is called <tt>Cache</tt>. It can host multiple <tt>Cache</tt> instances per "runtime".</p> <p style="margin: 10px 0 0">A user then defines a domain model like follows for a SessionFactory configured to use Cacheaholic:</p>
<div class="code panel" style="border-width: 1px;; border: 1px solid #cccccc; background: #f5f5f5; font-size: 12px; line-height: 1.333; font-family: monospace; border: 1px solid #cccccc; -moz-border-radius: 3px; border-radius: 3px; margin: 9px 0">
<div class="codeContent panelContent" style="padding: 9px 12px">
<pre class="code-java" style="margin: 10px 0 0; margin-top: 0; max-height: 30em; overflow: auto; white-space: pre-wrap; word-wrap: normal">
@Cache(region=<span class="code-quote" style="color: #009100">"a.b.c"</span>,usage=TRANSACTIONAL)
<span class="code-keyword" style="color: #000091">public</span> class Person {
...
@Cache(region=<span class="code-quote" style="color: #009100">"a.b.c"</span>,usage=TRANSACTIONAL)
@ManyToMany..
Collection<Person> friends;
}
</pre>
</div>
</div> <p style="margin: 10px 0 0">So to be clear, here we have:</p>
<ol>
<li>2 references to the region name "a.b.c" - one to store Person entity data, another to store Person#friends data. Perfectly valid as discussed above</li>
<li>Both accesses to this "a.b.c" region happen to use the same AccessType for this example - again this is what you want to bake in as a restriction - we will come back to this in another example...</li>
</ol> <p style="margin: 10px 0 0">This will cause the following calls to happen when Hibernate bootstraps the SF...</p>
<ol>
<li>CacheaholicRegionFactory#<init> (see previous discussion)</li>
<li>CacheaholicRegionFactory#buildRegion( "a.b.c" ) - Hibernate caches this based on region name</li>
<li>CacheaholicRegion<span class="error">["a.b.c"]</span>#buildEntityRegionAccess(AccessType.TRANSACTIONAL, EntityCacheDataDescription<span class="error">[Person]</span>)</li>
<li>CacheaholicRegion<span class="error">["a.b.c"]</span>#buildCollectionRegionAccess(AccessType.TRANSACTIONAL, CollectionCacheDataDescription<a href="#friends" style="color: #3b73af; text-decoration: none">Person#friends</a>)</li>
</ol> <p style="margin: 10px 0 0">That's it. Hibernate caches these references it gets back - so we won't keep calling this over and over for the same args.</p> <p style="margin: 10px 0 0">What I would envision doing as the CacheaholicRegionFactory developer would be to:</p>
<ol>
<li>Write CacheaholicRegionFactory such that it has a reference to Cacheaholic's underlying <tt>CacheTemplateRepository</tt> which gets a series of named config templates for creating Cacheaholic <tt>Cache</tt> impls. We'll come back to this...</li>
<li>When CacheaholicRegionFactory is asked to build a Region, to me that would imply a <b>possible</b> <tt>CacheTemplate</tt> based on the region name.</li>
<li>Additionally, when CacheaholicRegion is asked to build a UserModelRegionAccess it now has 2 additional possible hints as to the <tt>CacheTemplate</tt> to use:
<ol>
<li>Based on the role name - i.e. "Person" v. "Person#friends"</li>
<li>Based on the type of data to be cached - entity v. collection v. natural-id</li>
</ol> </li>
</ol> <p style="margin: 10px 0 0">In terms of these "templates", what I would envision is a series of resolution steps - more-specific to least:</p>
<ol>
<li>See if there is a <tt>CacheTemplate</tt> keyed by the role name; if so use that...</li>
<li>See if there is a <tt>CacheTemplate</tt> keyed by the region name; if so use that...</li>
<li>See if there is a <tt>CacheTemplate</tt> keyed for the type of data - "entity", "collection", etc. Or maybe even "hibernate-entity", etc; if so use that...</li>
<li>Otherwise use some "default" <tt>CacheTemplate</tt>.</li>
</ol> <p style="margin: 10px 0 0">Regardless of which <tt>CacheTemplate</tt> is used, when we build a Cacheaholic UserModelRegionAccess impl, it would hold a reference to the underlying Cacheaholic <tt>Cache</tt> where its data is stored.</p>
<hr> <p style="margin: 10px 0 0">So let's apply this to your concern over mixed AccessTypes...</p>
<div class="code panel" style="border-width: 1px;; border: 1px solid #cccccc; background: #f5f5f5; font-size: 12px; line-height: 1.333; font-family: monospace; border: 1px solid #cccccc; -moz-border-radius: 3px; border-radius: 3px; margin: 9px 0">
<div class="codeContent panelContent" style="padding: 9px 12px">
<pre class="code-java" style="margin: 10px 0 0; margin-top: 0; max-height: 30em; overflow: auto; white-space: pre-wrap; word-wrap: normal">
@Cache(region=<span class="code-quote" style="color: #009100">"a.b.c"</span>,usage=TRANSACTIONAL)
<span class="code-keyword" style="color: #000091">public</span> class Person {
...
@Cache(region=<span class="code-quote" style="color: #009100">"a.b.c"</span>,usage=READ_WRITE)
@ManyToMany..
Collection<Person> friends;
}
</pre>
</div>
</div> <p style="margin: 10px 0 0">Again, bear in mind that each of these is getting mapped to individual RegionAccess objects (individual Cacheaholic <tt>Cache</tt> impls). So I am just not seeing how that is a problem. </p> <p style="margin: 10px 0 0"><b>Now</b> I can see it being a problem depending on how a provider decided to implement Region/RegionAccess. But that would be an implementation problem <img class="emoticon" src="cid:jira-generated-image-static-wink-dc46f6a4-dca8-4a02-8ac0-b6fcfa7dd769" height="16" width="16" align="absmiddle" alt="" border="0"></p> </td>
</tr>
</tbody>
</table> </td>
</tr>
<tr>
<td class="email-content-main mobile-expand " style="padding: 0; border-collapse: collapse; border-left: 1px solid #cccccc; border-right: 1px solid #cccccc; border-top: 0; border-bottom: 0; padding: 0 15px 0 16px; background-color: #ffffff" bgcolor="#ffffff"> <script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"description": "View Issue",
"potentialAction": {
"@type": "ViewAction",
"target": "https://hibernate.atlassian.net/browse/HHH-11356?inbox=true&focusedCommentId=90111&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-90111",
"name": "View Comment"
},
"publisher": {
"@type": "Organization",
"name": "Atlassian",
"url": "https://www.atlassian.com"
}
}
</script>
<table id="actions-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0; mso-table-rspace: 0; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px">
<tbody>
<tr>
<td id="actions-pattern-container" valign="middle" style="padding: 0; border-collapse: collapse; padding: 10px 0 10px 24px; vertical-align: middle; padding-left: 0">
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0; mso-table-rspace: 0">
<tbody>
<tr>
<td class="actions-pattern-action-icon-container" style="padding: 0; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0; vertical-align: middle"> <a href="https://hibernate.atlassian.net/browse/HHH-11356#add-comment" target="_blank" title="Add Comment" style="color: #3b73af; text-decoration: none"> <img class="actions-pattern-action-icon-image" src="cid:jira-generated-image-static-comment-icon-61dd4d33-3a9a-4fb0-b7ee-9c9a6f0817fa" alt="Add Comment" title="Add Comment" height="16" width="16" border="0" style="vertical-align: middle"> </a> </td>
<td class="actions-pattern-action-text-container" style="padding: 0; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px"> <a href="https://hibernate.atlassian.net/browse/HHH-11356#add-comment" target="_blank" title="Add Comment" style="color: #3b73af; text-decoration: none">Add Comment</a> </td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
</table> </td>
</tr>
<!-- there needs to be content in the cell for it to render in some clients -->
<tr>
<td class="email-content-rounded-bottom mobile-expand" style="padding: 0; border-collapse: collapse; color: #ffffff; padding: 0 15px 0 16px; height: 5px; line-height: 5px; background-color: #ffffff; border-top: 0; border-left: 1px solid #cccccc; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; mso-line-height-rule: exactly" height="5" bgcolor="#ffffff"> </td>
</tr>
</tbody>
</table> </td>
</tr>
<tr>
<td id="footer-pattern" style="padding: 0; border-collapse: collapse; padding: 12px 20px">
<table id="footer-pattern-container" cellspacing="0" cellpadding="0" border="0" style="border-collapse: collapse; mso-table-lspace: 0; mso-table-rspace: 0">
<tbody>
<tr>
<td id="footer-pattern-text" class="mobile-resize-text" width="100%" style="padding: 0; border-collapse: collapse; color: #999999; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px"> This message was sent by Atlassian JIRA <span id="footer-build-information">(v1000.747.1#100028-<span title="3d05bd69f16f8de5a8061c8aed7fc0a7dba99d65" data-commit-id="3d05bd69f16f8de5a8061c8aed7fc0a7dba99d65}">sha1:3d05bd6</span>)</span> </td>
<td id="footer-pattern-logo-desktop-container" valign="top" style="padding: 0; border-collapse: collapse; padding-left: 20px; vertical-align: top">
<table style="border-collapse: collapse; mso-table-lspace: 0; mso-table-rspace: 0">
<tbody>
<tr>
<td id="footer-pattern-logo-desktop-padding" style="padding: 0; border-collapse: collapse; padding-top: 3px"> <img id="footer-pattern-logo-desktop" src="cid:jira-generated-image-static-footer-desktop-logo-cb9fd72d-15b0-488d-b0ee-bcd31691ae19" alt="Atlassian logo" title="Atlassian logo" width="169" height="36" class="image_fix"> </td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
</table>
</body>
</html>