{"id":64935,"date":"2017-04-10T13:00:59","date_gmt":"2017-04-10T10:00:59","guid":{"rendered":"https:\/\/www.javacodegeeks.com\/?p=64935"},"modified":"2017-04-09T11:58:14","modified_gmt":"2017-04-09T08:58:14","slug":"distributed-cache-overview","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html","title":{"rendered":"Distributed Cache \u2013 Overview"},"content":{"rendered":"<p>What\u2019s a distributed cache? A solution that is \u201cdeployed\u201d in an application (typically a web application) and that makes sure data is loaded from memory, rather than from disk (which is much slower), in order to improve performance and response time.<\/p>\n<p>That looks easy if the cache is to be used on a single machine \u2013 you just load your most active data from the database in memory (e.g. a Guava Cache instance), and serve it from there. It becomes a bit more complicated when this has to work in a cluster \u2013 e.g. 5 application nodes serving requests to users in a round-robin fashion.<\/p>\n<p>You have to update the in-memory cache on all machines each time a piece of data is updated by a request to one of the machines. If you just load all the data in memory and don\u2019t invalidate it, the cache won\u2019t be \u201ccoherent\u201d \u2013 it will have stale values and requests to different application nodes will have different results, which you most certainly want to avoid. Or you can have a single big cache server with tons of memory, but it can die \u2013 and that may disrupt the smooth operation, so you\u2019d want to have at least 2 machines in a cluster.<\/p>\n<p>You can get a distributed cache in different ways. To list a few: Infinispan (<a href=\"https:\/\/www.javacodegeeks.com\/2016\/02\/setting-distributed-infinispan-cache-hibernate-spring.html\">which I\u2019ve covered previously<\/a>), Terracotta\/Ehcache, Hazelcast, Memcached, Redis, Cassandra, Elasticache(by Amazon). The former three are Java-specific (both JCache compliant), but the rest can be used in any setup. Cassandra wasn\u2019t initially meant to be cache solution, but it can easily be used as such.<\/p>\n<p>All of these have different configurations and different options, even different architectures. For example, you can run Ehcache with a central Terracotta server, or with peer-to-peer gossip protocol. The in-process approach is also applicable for Infinispan and Hazelcast. Alternatively, you can rely on a cloud-provided service, like Elasticache, or you can setup your own cluster of Memcached\/Redis\/Cassandra servers. Having the cache on the application nodes themselves is slightly faster than having a dedicated memory server (cluster), because of the network overhead.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>The cache is structured around keys and values \u2013 there\u2019s a cached entry for each key. When you want to load something form the database, you first check whether the cache doesn\u2019t have an entry with that key (based on the ID of your database record, for example). If a key exists in the cache, you don\u2019t do a database query.<\/p>\n<p>But how is the data \u201cdistributed\u201d? It wouldn\u2019t make sense to load all the data on all nodes at the same time, as the duplication is a waste of space and keeping the cache coherent would again be a problem. Most of the solutions rely on the so called <a href=\"https:\/\/en.wikipedia.org\/wiki\/Consistent_hashing\">\u201cconsistent hashing\u201d<\/a>. When you look for a particular key, its hash is calculated and (depending on the number of machines in the cache cluster), the cache solution knows exactly on which machine the corresponding value is located. You can read more details in the wikipedia article, but the approach works even when you add or remove nodes from the cache cluster, i.e. the cluster of machines that hold the cached data.<\/p>\n<p>Then, when you do an update, you also update the cache entry, which the caching solution propagates in order to make the cache coherent. Note that if you do manual updates directly in the database, the cache will have stale data.<\/p>\n<p>On the application level, you\u2019d normally want to abstract the interactions with the cache. You\u2019d end up with something like a generic \u201cget\u201d method that checks the cache and only then goes to the database. This is true for get-by-id queries, but caches can also be applied for other SELECT queries \u2013 you just use the query as a key, and the query result as value. For updates it would similarly update the database and the cache.<\/p>\n<p>Some frameworks offer these abstractions out of the box \u2013 ORMs like Hibernate have the so-called cache providers, so you just add a configuration option saying \u201cI want to use (2nd level) cache\u201d and your ORM operations automatically consult the configured cache provider before hitting the database. Spring has the <code>@Cacheable<\/code> annotation which can cache method invocations, using their parameters as keys. Other frameworks and languages usually have something like that as well.<\/p>\n<p>An important side-note \u2013 you may need to pre-load the cache. On a fresh startup of a cluster (e.g. after a <a href=\"https:\/\/www.javacodegeeks.com\/2015\/06\/blue-green-deployment-with-a-single-database.html\">new deployment in a blue-green deployment scheme<\/a>\/crash\/network failure\/etc.) the system may be slow to fill the cache. So you may have a batch job run on startup to fetch some pieces of data from the database and put them in the cache.<\/p>\n<p>It all sounds easy and that\u2019s good \u2013 the basic setup covers most of the cases. In reality it\u2019s a bit more complicated to tweak the cache configurations. Even when you manage to setup a cluster (which can be challenging in, say, AWS), your cache strategies may not be straightforward. You have to answer a couple of questions that may be important \u2013 how much do you want your cache entries to live? How big do you need your cache to be? How should elements expire (cache eviction strategy) \u2013 least recently used, least frequently used, first-in-first-out?<\/p>\n<p>These options often sound arbitrary. You normally go with the defaults and don\u2019t bother. But you have to constantly keep on eye on the cache statistics, do performances tests, measure and tweak. Sometimes a single configuration option can have a big impact.<\/p>\n<p>One important note here on the measuring side \u2013 you don\u2019t necessarily want to cache everything. You can start that way, but it may turn out that for some types of entries you are actually better off without a cache. Normally these are the ones that are updated too often and read not that often, so constantly updating the cache with them is an overhead that doesn\u2019t pay off. So \u2013 measure, tweak, repeat.<\/p>\n<p>Distributed caches are an almost mandatory component of web applications. Yet, I\u2019ve had numerous discussions about how a given system is very big and needs a lot of hardware, where all the data would fit in my laptop\u2019s memory. So, much to my surprise, it turns out it\u2019s not yet a universally known concept. I hope I\u2019ve given a short, but sufficient overview of the concept and the various options.<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"https:\/\/techblog.bozho.net\/distributed-cache-overview\/\">Distributed Cache \u2013 Overview<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/join-us\/jcg\/\">JCG partner<\/a> Bozhidar Bozhanov at the <a href=\"http:\/\/techblog.bozho.net\/\">Bozho&#8217;s tech blog<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>What\u2019s a distributed cache? A solution that is \u201cdeployed\u201d in an application (typically a web application) and that makes sure data is loaded from memory, rather than from disk (which is much slower), in order to improve performance and response time. That looks easy if the cache is to be used on a single machine &hellip;<\/p>\n","protected":false},"author":55,"featured_media":2386,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[],"class_list":["post-64935","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-development"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Distributed Cache \u2013 Overview - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"What\u2019s a distributed cache? A solution that is \u201cdeployed\u201d in an application (typically a web application) and that makes sure data is loaded from memory,\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Distributed Cache \u2013 Overview - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"What\u2019s a distributed cache? A solution that is \u201cdeployed\u201d in an application (typically a web application) and that makes sure data is loaded from memory,\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2017-04-10T10:00:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Bozhidar Bozhanov\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Bozhidar Bozhanov\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/04\\\/distributed-cache-overview.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/04\\\/distributed-cache-overview.html\"},\"author\":{\"name\":\"Bozhidar Bozhanov\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/1eaacbb8d159c99fd32e6b51198a1e79\"},\"headline\":\"Distributed Cache \u2013 Overview\",\"datePublished\":\"2017-04-10T10:00:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/04\\\/distributed-cache-overview.html\"},\"wordCount\":1102,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/04\\\/distributed-cache-overview.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/software-development-2-logo.jpg\",\"articleSection\":[\"Software Development\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/04\\\/distributed-cache-overview.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/04\\\/distributed-cache-overview.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/04\\\/distributed-cache-overview.html\",\"name\":\"Distributed Cache \u2013 Overview - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/04\\\/distributed-cache-overview.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/04\\\/distributed-cache-overview.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/software-development-2-logo.jpg\",\"datePublished\":\"2017-04-10T10:00:59+00:00\",\"description\":\"What\u2019s a distributed cache? A solution that is \u201cdeployed\u201d in an application (typically a web application) and that makes sure data is loaded from memory,\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/04\\\/distributed-cache-overview.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/04\\\/distributed-cache-overview.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/04\\\/distributed-cache-overview.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/software-development-2-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/software-development-2-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/04\\\/distributed-cache-overview.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Software Development\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/software-development\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Distributed Cache \u2013 Overview\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/1eaacbb8d159c99fd32e6b51198a1e79\",\"name\":\"Bozhidar Bozhanov\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/12\\\/bozhidar.bozhanov.jpg\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/12\\\/bozhidar.bozhanov.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/12\\\/bozhidar.bozhanov.jpg\",\"caption\":\"Bozhidar Bozhanov\"},\"description\":\"Senior Java developer, one of the top stackoverflow users, fluent with Java and Java technology stacks - Spring, JPA, JavaEE, as well as Android, Scala and any framework you throw at him. creator of Computoser - an algorithmic music composer. Worked on telecom projects, e-government and large-scale online recruitment and navigation platforms.\",\"sameAs\":[\"http:\\\/\\\/techblog.bozho.net\\\/\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/bozhidar-bozhanov\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Distributed Cache \u2013 Overview - Java Code Geeks","description":"What\u2019s a distributed cache? A solution that is \u201cdeployed\u201d in an application (typically a web application) and that makes sure data is loaded from memory,","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html","og_locale":"en_US","og_type":"article","og_title":"Distributed Cache \u2013 Overview - Java Code Geeks","og_description":"What\u2019s a distributed cache? A solution that is \u201cdeployed\u201d in an application (typically a web application) and that makes sure data is loaded from memory,","og_url":"https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2017-04-10T10:00:59+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","type":"image\/jpeg"}],"author":"Bozhidar Bozhanov","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Bozhidar Bozhanov","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html"},"author":{"name":"Bozhidar Bozhanov","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/1eaacbb8d159c99fd32e6b51198a1e79"},"headline":"Distributed Cache \u2013 Overview","datePublished":"2017-04-10T10:00:59+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html"},"wordCount":1102,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","articleSection":["Software Development"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html","url":"https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html","name":"Distributed Cache \u2013 Overview - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","datePublished":"2017-04-10T10:00:59+00:00","description":"What\u2019s a distributed cache? A solution that is \u201cdeployed\u201d in an application (typically a web application) and that makes sure data is loaded from memory,","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2017\/04\/distributed-cache-overview.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Software Development","item":"https:\/\/www.javacodegeeks.com\/category\/software-development"},{"@type":"ListItem","position":3,"name":"Distributed Cache \u2013 Overview"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/1eaacbb8d159c99fd32e6b51198a1e79","name":"Bozhidar Bozhanov","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/12\/bozhidar.bozhanov.jpg","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/12\/bozhidar.bozhanov.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/12\/bozhidar.bozhanov.jpg","caption":"Bozhidar Bozhanov"},"description":"Senior Java developer, one of the top stackoverflow users, fluent with Java and Java technology stacks - Spring, JPA, JavaEE, as well as Android, Scala and any framework you throw at him. creator of Computoser - an algorithmic music composer. Worked on telecom projects, e-government and large-scale online recruitment and navigation platforms.","sameAs":["http:\/\/techblog.bozho.net\/"],"url":"https:\/\/www.javacodegeeks.com\/author\/bozhidar-bozhanov"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/64935","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/55"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=64935"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/64935\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/2386"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=64935"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=64935"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=64935"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}