{"id":544,"date":"2015-01-07T17:47:32","date_gmt":"2015-01-08T02:47:32","guid":{"rendered":"http:\/\/blog.box.kr\/?p=544"},"modified":"2015-01-07T17:47:32","modified_gmt":"2015-01-08T02:47:32","slug":"%ed%95%98%ec%9d%b4%eb%b2%84%eb%84%a4%ec%9d%b4%ed%8a%b8-%ec%82%ac%ec%9a%a9%ec%8b%9c%ec%97%90-%ec%98%a4%eb%9d%bc%ed%81%b4%ec%97%90%ec%84%9c-%eb%82%a0%ec%a7%9c-%ed%98%95%ec%8b%9d%ec%9c%bc%eb%a1%9c","status":"publish","type":"post","link":"https:\/\/blog.box.kr\/?p=544","title":{"rendered":"\ud558\uc774\ubc84\ub124\uc774\ud2b8 \uc0ac\uc6a9\uc2dc\uc5d0 \uc624\ub77c\ud074\uc5d0\uc11c \ub0a0\uc9dc \ud615\uc2dd\uc73c\ub85c \uc870\ud68c\uc2dc\uc5d0 Index \uc548"},"content":{"rendered":"<p>\ud558\uc774\ubc84\ub124\uc774\ud2b8 \uc0ac\uc6a9\uc2dc\uc5d0 \uc624\ub77c\ud074\uc5d0\uc11c \ub0a0\uc9dc \ud615\uc2dd\uc73c\ub85c \uc870\ud68c\uc2dc\uc5d0 Index \uc548\ud0c0\ub294 \ubb38\uc81c\uac00 \ubc1c\uc0dd..<\/p>\n<p>&nbsp;<\/p>\n<p>\ub0b4\uc6a9\uc744 \uc694\uc57d\ud558\uba74.. \ud558\uc774\ubc84\ub124\uc774\ud2b8\uac00 \ub0a0\uc9dc \ud615\uc2dd\uc73c\ub85c \uc778\uc2dd \ubabb\ud558\uace0 \ud30c\ub77c\ubbf8\ud130 \uae30\uc900\uc73c\ub85c<br \/>\n\ubb38\uc790 ( \ud544\ub4dc ) \uc640 \ub0a0\uc9dc ( \ud30c\ub77c\ubbf8\ud130)\ub77c \ud310\ub2e8 \ud558\uace0 \ud544\ub4dc\ub97c \ud568\uc218 \uc4b8\uc5b4\uc11c<br \/>\n\ub0a0\uc9dc \ud615\uc2dd\uc73c\ub85c \ubcc0\uacbd \ud568.. \uadf8\ub798\uc11c \uc778\ub371\uc2a4 \ubabb \ud0d0..<\/p>\n<p>\uacb0\ub860 \uc801\uc73c\ub85c \ud558\uc774\ubc84 \ub124\uc774\ud2b8\ud55c\ub370 \uc774 \ud544\ub4dc\uac00 \ub0a0\uc9dc \ud615\uc2dd\uc774\ub77c\ub294\uac78 \uc778\uc2dd \ud574\uc918\uc57c \ud568.<\/p>\n<div class=\"content\">\n<h2>What is the problem with Oracle DATE?<\/h2>\n<p>The problem that was presented in the previous article is dealing with the fact that if a query uses filters on Oracle\u00a0<code>DATE<\/code>\u00a0columns:<\/p>\n<div id=\"highlighter_934354\" class=\"syntaxhighlighter \">\n<div class=\"bar\">\n<div class=\"toolbar\"><a class=\"item viewSource\" title=\"view source\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#viewSource\">view source<\/a><\/p>\n<div class=\"item copyToClipboard\">\n<\/div>\n<p><a class=\"item printSource\" title=\"print\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#printSource\">print<\/a><a class=\"item about\" title=\"?\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#about\">?<\/a>\n<\/div>\n<\/div>\n<div class=\"lines\">\n<div class=\"line alt1\"><code class=\"number\">1.<\/code><span class=\"content\"><span class=\"block\"><code class=\"comments\">\/\/ execute_at is of type DATE and there's an index<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">2.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">PreparedStatement stmt = connection.prepareStatement(<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">3.<\/code><span class=\"content\"><span class=\"block\"><code class=\"string\">\"SELECT * \"<\/code> <code class=\"plain\">+<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">4.<\/code><span class=\"content\"><span class=\"block\"><code class=\"string\">\"FROM rentals \"<\/code> <code class=\"plain\">+<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">5.<\/code><span class=\"content\"><span class=\"block\"><code class=\"string\">\"WHERE rental_date &gt; ? AND rental_date &lt; ?\"<\/code><code class=\"plain\">);<\/code><\/span><\/span>\n<\/div>\n<\/div>\n<\/div>\n<p>\u2026 and we\u2019re using\u00a0<code>java.sql.Timestamp<\/code>\u00a0for our bind values:<\/p>\n<div id=\"highlighter_345696\" class=\"syntaxhighlighter \">\n<div class=\"bar\">\n<div class=\"toolbar\"><a class=\"item viewSource\" title=\"view source\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#viewSource\">view source<\/a><\/p>\n<div class=\"item copyToClipboard\">\n<\/div>\n<p><a class=\"item printSource\" title=\"print\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#printSource\">print<\/a><a class=\"item about\" title=\"?\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#about\">?<\/a>\n<\/div>\n<\/div>\n<div class=\"lines\">\n<div class=\"line alt1\"><code class=\"number\">1.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">stmt.setTimestamp(<\/code><code class=\"value\">1<\/code><code class=\"plain\">, start);<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">2.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">stmt.setTimestamp(<\/code><code class=\"value\">2<\/code><code class=\"plain\">, end);<\/code><\/span><\/span>\n<\/div>\n<\/div>\n<\/div>\n<p>\u2026 then the execution plan will turn very bad with a FULL TABLE SCAN or perhaps an INDEX FULL SCAN, even if we should have gotten a regular INDEX RANGE SCAN.<\/p>\n<pre>-------------------------------------\n| Id  | Operation          | Name   |\n-------------------------------------\n|   0 | SELECT STATEMENT   |        |\n|*  1 |  FILTER            |        |\n|*  2 |   TABLE ACCESS FULL| RENTAL |\n-------------------------------------\n\nPredicate Information (identified by operation id):\n---------------------------------------------------\n\n   1 - filter(:1&lt;=:2)\n   2 - filter((INTERNAL_FUNCTION(\"RENTAL_DATE\")&gt;=:1 AND\n              INTERNAL_FUNCTION(\"RENTAL_DATE\")&lt;=:2))\n<\/pre>\n<p>This is because the database column is widened from Oracle\u00a0<code>DATE<\/code>\u00a0to Oracle<code>TIMESTAMP<\/code>\u00a0via this\u00a0<em><code>INTERNAL_FUNCTION()<\/code><\/em>, rather than truncating the<code>java.sql.Timestamp<\/code>\u00a0value to Oracle\u00a0<code>DATE<\/code>.<\/p>\n<p><a href=\"http:\/\/blog.jooq.org\/2014\/12\/22\/are-you-binding-your-oracle-dates-correctly-i-bet-you-arent\/\">More details about the problem itself can be seen in the previous article<\/a><\/p>\n<h2>Preventing this INTERNAL_FUNCTION() with Hibernate<\/h2>\n<p>You\u00a0<em>can<\/em>\u00a0fix this with Hibernate\u2019s proprietary API, using a<a href=\"http:\/\/docs.jboss.org\/hibernate\/orm\/4.3\/manual\/en-US\/html_single\/#types-custom-ut\"><code>org.hibernate.usertype.UserType<\/code><\/a>.<\/p>\n<p>Assuming that we have the following entity:<\/p>\n<div id=\"highlighter_822517\" class=\"syntaxhighlighter \">\n<div class=\"bar\">\n<div class=\"toolbar\"><a class=\"item viewSource\" title=\"view source\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#viewSource\">view source<\/a><\/p>\n<div class=\"item copyToClipboard\">\n<\/div>\n<p><a class=\"item printSource\" title=\"print\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#printSource\">print<\/a><a class=\"item about\" title=\"?\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#about\">?<\/a>\n<\/div>\n<\/div>\n<div class=\"lines\">\n<div class=\"line alt1\"><code class=\"number\">01.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Entity<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">02.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"keyword\">class<\/code> <code class=\"plain\">Rental {<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">03.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">04.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Id<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">05.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Column<\/code><code class=\"plain\">(name = <\/code><code class=\"string\">\"rental_id\"<\/code><code class=\"plain\">)<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">06.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"plain\">Long rentalId;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">07.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">08.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Column<\/code><code class=\"plain\">(name = <\/code><code class=\"string\">\"rental_date\"<\/code><code class=\"plain\">)<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">09.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"plain\">Timestamp rentalDate;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">10.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">}<\/code><\/span><\/span>\n<\/div>\n<\/div>\n<\/div>\n<p>And now, let\u2019s run this query here (I\u2019m using Hibernate API, not JPA, for the example):<\/p>\n<div id=\"highlighter_817333\" class=\"syntaxhighlighter \">\n<div class=\"bar\">\n<div class=\"toolbar\"><a class=\"item viewSource\" title=\"view source\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#viewSource\">view source<\/a><\/p>\n<div class=\"item copyToClipboard\">\n<\/div>\n<p><a class=\"item printSource\" title=\"print\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#printSource\">print<\/a><a class=\"item about\" title=\"?\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#about\">?<\/a>\n<\/div>\n<\/div>\n<div class=\"lines\">\n<div class=\"line alt1\"><code class=\"number\">1.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">List&lt;Rental&gt; rentals =<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">2.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">session.createQuery(<\/code><code class=\"string\">\"from Rental r where r.rentalDate between :from and :to\"<\/code><code class=\"plain\">)<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">3.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">.setParameter(<\/code><code class=\"string\">\"from\"<\/code><code class=\"plain\">, Timestamp.valueOf(<\/code><code class=\"string\">\"2000-01-01 00:00:00.0\"<\/code><code class=\"plain\">))<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">4.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">.setParameter(<\/code><code class=\"string\">\"to\"<\/code><code class=\"plain\">, Timestamp.valueOf(<\/code><code class=\"string\">\"2000-10-01 00:00:00.0\"<\/code><code class=\"plain\">))<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">5.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">.list();<\/code><\/span><\/span>\n<\/div>\n<\/div>\n<\/div>\n<p>The execution plan that we\u2019re now getting is again inefficient:<\/p>\n<pre>-------------------------------------\n| Id  | Operation          | Name   |\n-------------------------------------\n|   0 | SELECT STATEMENT   |        |\n|*  1 |  FILTER            |        |\n|*  2 |   TABLE ACCESS FULL| RENTAL |\n-------------------------------------\n\nPredicate Information (identified by operation id):\n---------------------------------------------------\n\n   1 - filter(:1&lt;=:2)\n   2 - filter((INTERNAL_FUNCTION(\"RENTAL0_\".\"RENTAL_DATE\")&gt;=:1 AND\n              INTERNAL_FUNCTION(\"RENTAL0_\".\"RENTAL_DATE\")&lt;=:2))\n<\/pre>\n<p>The solution is to add this\u00a0<code>@Type<\/code>\u00a0annotation to all relevant columns\u2026<\/p>\n<div id=\"highlighter_150171\" class=\"syntaxhighlighter \">\n<div class=\"bar\">\n<div class=\"toolbar\"><a class=\"item viewSource\" title=\"view source\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#viewSource\">view source<\/a><\/p>\n<div class=\"item copyToClipboard\">\n<\/div>\n<p><a class=\"item printSource\" title=\"print\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#printSource\">print<\/a><a class=\"item about\" title=\"?\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#about\">?<\/a>\n<\/div>\n<\/div>\n<div class=\"lines\">\n<div class=\"line alt1\"><code class=\"number\">01.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Entity<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">02.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@TypeDefs<\/code><code class=\"plain\">(<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">03.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">value = <\/code><code class=\"color1\">@TypeDef<\/code><code class=\"plain\">(<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">04.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">name = <\/code><code class=\"string\">\"oracle_date\"<\/code><code class=\"plain\">,<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">05.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">typeClass = OracleDate.<\/code><code class=\"keyword\">class<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">06.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">)<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">07.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">)<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">08.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"keyword\">class<\/code> <code class=\"plain\">Rental {<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">09.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">10.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Id<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">11.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Column<\/code><code class=\"plain\">(name = <\/code><code class=\"string\">\"rental_id\"<\/code><code class=\"plain\">)<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">12.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"plain\">Long rentalId;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">13.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">14.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Column<\/code><code class=\"plain\">(name = <\/code><code class=\"string\">\"rental_date\"<\/code><code class=\"plain\">)<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">15.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Type<\/code><code class=\"plain\">(type = <\/code><code class=\"string\">\"oracle_date\"<\/code><code class=\"plain\">)<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">16.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"plain\">Timestamp rentalDate;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">17.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">}<\/code><\/span><\/span>\n<\/div>\n<\/div>\n<\/div>\n<p>and register the following, simplified\u00a0<code>UserType<\/code>:<\/p>\n<div id=\"highlighter_133433\" class=\"syntaxhighlighter \">\n<div class=\"bar\">\n<div class=\"toolbar\"><a class=\"item viewSource\" title=\"view source\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#viewSource\">view source<\/a><\/p>\n<div class=\"item copyToClipboard\">\n<\/div>\n<p><a class=\"item printSource\" title=\"print\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#printSource\">print<\/a><a class=\"item about\" title=\"?\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#about\">?<\/a>\n<\/div>\n<\/div>\n<div class=\"lines\">\n<div class=\"line alt1\"><code class=\"number\">01.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">java.io.Serializable;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">02.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">java.sql.PreparedStatement;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">03.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">java.sql.ResultSet;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">04.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">java.sql.SQLException;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">05.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">java.sql.Timestamp;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">06.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">java.sql.Types;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">07.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">java.util.Objects;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">08.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">09.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">oracle.sql.DATE;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">10.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">11.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">org.hibernate.engine.spi.SessionImplementor;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">12.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">org.hibernate.usertype.UserType;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">13.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">14.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"keyword\">class<\/code> <code class=\"plain\">OracleDate <\/code><code class=\"keyword\">implements<\/code> <code class=\"plain\">UserType {<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">15.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">16.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Override<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">17.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"keyword\">int<\/code><code class=\"plain\">[] sqlTypes() {<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">18.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">return<\/code> <code class=\"keyword\">new<\/code> <code class=\"keyword\">int<\/code><code class=\"plain\">[] { Types.TIMESTAMP };<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">19.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">}<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">20.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">21.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Override<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">22.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"plain\">Class&lt;?&gt; returnedClass() {<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">23.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">return<\/code> <code class=\"plain\">Timestamp.<\/code><code class=\"keyword\">class<\/code><code class=\"plain\">;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">24.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">}<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">25.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">26.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Override<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">27.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"plain\">Object nullSafeGet(<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">28.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">ResultSet rs,<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">29.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">String[] names,<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">30.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">SessionImplementor session,<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">31.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">Object owner<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">32.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">)<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">33.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">throws<\/code> <code class=\"plain\">SQLException {<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">34.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">return<\/code> <code class=\"plain\">rs.getTimestamp(names[<\/code><code class=\"value\">0<\/code><code class=\"plain\">]);<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">35.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">}<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">36.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">37.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Override<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">38.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"keyword\">void<\/code> <code class=\"plain\">nullSafeSet(<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">39.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">PreparedStatement st,<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">40.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">Object value,<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">41.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">int<\/code> <code class=\"plain\">index,<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">42.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">SessionImplementor session<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">43.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">)<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">44.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">throws<\/code> <code class=\"plain\">SQLException {<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">45.<\/code><span class=\"content\"><span class=\"block\"><code class=\"comments\">\/\/ The magic is here: oracle.sql.DATE!<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">46.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">st.setObject(index, <\/code><code class=\"keyword\">new<\/code> <code class=\"plain\">DATE(value));<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">47.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">}<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">48.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">49.<\/code><span class=\"content\"><span class=\"block\"><code class=\"comments\">\/\/ The other method implementations are omitted<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">50.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">}<\/code><\/span><\/span>\n<\/div>\n<\/div>\n<\/div>\n<p>This will work because using the vendor-specific\u00a0<code>oracle.sql.DATE<\/code>\u00a0type will have the same effect on your execution plan as\u00a0<a href=\"http:\/\/blog.jooq.org\/2014\/12\/22\/are-you-binding-your-oracle-dates-correctly-i-bet-you-arent\/\">explicitly casting the bind variable in your SQL statement, as shown in the previous article<\/a>:\u00a0<code>CAST(? AS DATE)<\/code>. The execution plan is now the desired one:<\/p>\n<pre>------------------------------------------------------\n| Id  | Operation                    | Name          |\n------------------------------------------------------\n|   0 | SELECT STATEMENT             |               |\n|*  1 |  FILTER                      |               |\n|   2 |   TABLE ACCESS BY INDEX ROWID| RENTAL        |\n|*  3 |    INDEX RANGE SCAN          | IDX_RENTAL_UQ |\n------------------------------------------------------\n\nPredicate Information (identified by operation id):\n---------------------------------------------------\n\n   1 - filter(:1&lt;=:2)\n   3 - access(\"RENTAL0_\".\"RENTAL_DATE\"&gt;=:1\n          AND \"RENTAL0_\".\"RENTAL_DATE\"&lt;=:2)\n<\/pre>\n<p>If you want to reproduce this issue, just query any Oracle\u00a0<code>DATE<\/code>\u00a0column with a<code>java.sql.Timestamp<\/code>\u00a0bind value through JPA \/ Hibernate,\u00a0<a title=\"How to get Oracle execution plans with Starts, E-Rows, A-Rows and A-Time columns\" href=\"http:\/\/blog.jooq.org\/2012\/09\/19\/how-to-get-oracle-execution-plans-with-starts-e-rows-a-rows-and-a-time-columns\/\">and get the execution plan as indicated here<\/a>.<\/p>\n<p>Don\u2019t forget to flush shared pools and buffer caches to enforce the calculation of new plans between executions, because the generated SQL is the same each time.<\/p>\n<h2>Can I do it with JPA 2.1?<\/h2>\n<p>At first sight, it looks like the new converter feature in JPA 2.1 (<a href=\"http:\/\/www.jooq.org\/doc\/latest\/manual\/sql-execution\/fetching\/data-type-conversion\/\">which works just like jOOQ\u2019s converter feature<\/a>) should be able to do the trick. We should be able to write:<\/p>\n<div id=\"highlighter_77646\" class=\"syntaxhighlighter \">\n<div class=\"bar\">\n<div class=\"toolbar\"><a class=\"item viewSource\" title=\"view source\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#viewSource\">view source<\/a><\/p>\n<div class=\"item copyToClipboard\">\n<\/div>\n<p><a class=\"item printSource\" title=\"print\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#printSource\">print<\/a><a class=\"item about\" title=\"?\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#about\">?<\/a>\n<\/div>\n<\/div>\n<div class=\"lines\">\n<div class=\"line alt1\"><code class=\"number\">01.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">java.sql.Timestamp;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">02.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">03.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">javax.persistence.AttributeConverter;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">04.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">javax.persistence.Converter;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">05.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">06.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">oracle.sql.DATE;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">07.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">08.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Converter<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">09.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"keyword\">class<\/code> <code class=\"plain\">OracleDateConverter<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">10.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">implements<\/code> <code class=\"plain\">AttributeConverter&lt;Timestamp, DATE&gt;{<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">11.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">12.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Override<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">13.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"plain\">DATE convertToDatabaseColumn(Timestamp attribute) {<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">14.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">return<\/code> <code class=\"plain\">attribute == <\/code><code class=\"keyword\">null<\/code> <code class=\"plain\">? <\/code><code class=\"keyword\">null<\/code> <code class=\"plain\">: <\/code><code class=\"keyword\">new<\/code> <code class=\"plain\">DATE(attribute);<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">15.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">}<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">16.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">17.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Override<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">18.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"plain\">Timestamp convertToEntityAttribute(DATE dbData) {<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">19.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">return<\/code> <code class=\"plain\">dbData == <\/code><code class=\"keyword\">null<\/code> <code class=\"plain\">? <\/code><code class=\"keyword\">null<\/code> <code class=\"plain\">: dbData.timestampValue();<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">20.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">}<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">21.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">}<\/code><\/span><\/span>\n<\/div>\n<\/div>\n<\/div>\n<p>This converter can then be used with our entity:<\/p>\n<div id=\"highlighter_692975\" class=\"syntaxhighlighter \">\n<div class=\"bar\">\n<div class=\"toolbar\"><a class=\"item viewSource\" title=\"view source\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#viewSource\">view source<\/a><\/p>\n<div class=\"item copyToClipboard\">\n<\/div>\n<p><a class=\"item printSource\" title=\"print\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#printSource\">print<\/a><a class=\"item about\" title=\"?\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#about\">?<\/a>\n<\/div>\n<\/div>\n<div class=\"lines\">\n<div class=\"line alt1\"><code class=\"number\">01.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">java.sql.Timestamp;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">02.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">03.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">javax.persistence.Column;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">04.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">javax.persistence.Convert;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">05.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">javax.persistence.Entity;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">06.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">import<\/code> <code class=\"plain\">javax.persistence.Id;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">07.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">08.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Entity<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">09.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"keyword\">class<\/code> <code class=\"plain\">Rental {<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">10.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">11.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Id<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">12.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Column<\/code><code class=\"plain\">(name = <\/code><code class=\"string\">\"rental_id\"<\/code><code class=\"plain\">)<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">13.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"plain\">Long rentalId;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">14.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">15.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Column<\/code><code class=\"plain\">(name = <\/code><code class=\"string\">\"rental_date\"<\/code><code class=\"plain\">)<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">16.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Convert<\/code><code class=\"plain\">(converter = OracleDateConverter.<\/code><code class=\"keyword\">class<\/code><code class=\"plain\">)<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">17.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"plain\">Timestamp rentalDate;<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">18.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">}<\/code><\/span><\/span>\n<\/div>\n<\/div>\n<\/div>\n<p>But unfortunately, this doesn\u2019t work out of the box as Hibernate 4.3.7 will think that you\u2019re about to bind a variable of type\u00a0<code>VARBINARY<\/code>:<\/p>\n<div id=\"highlighter_528081\" class=\"syntaxhighlighter \">\n<div class=\"bar\">\n<div class=\"toolbar\"><a class=\"item viewSource\" title=\"view source\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#viewSource\">view source<\/a><\/p>\n<div class=\"item copyToClipboard\">\n<\/div>\n<p><a class=\"item printSource\" title=\"print\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#printSource\">print<\/a><a class=\"item about\" title=\"?\" href=\"http:\/\/java.dzone.com\/articles\/leaky-abstractions-or-how-bind?utm_content=buffer8f384&amp;utm_medium=social&amp;utm_source=facebook.com&amp;utm_campaign=buffer#about\">?<\/a>\n<\/div>\n<\/div>\n<div class=\"lines\">\n<div class=\"line alt1\"><code class=\"number\">01.<\/code><span class=\"content\"><span class=\"block\"><code class=\"comments\">\/\/ From org.hibernate.type.descriptor.sql.SqlTypeDescriptorRegistry<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">02.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">03.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">public<\/code> <code class=\"plain\">&lt;X&gt; ValueBinder&lt;X&gt; getBinder(JavaTypeDescriptor&lt;X&gt; javaTypeDescriptor) {<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">04.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">if<\/code> <code class=\"plain\">( Serializable.<\/code><code class=\"keyword\">class<\/code><code class=\"plain\">.isAssignableFrom( javaTypeDescriptor.getJavaTypeClass() ) ) {<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">05.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">return<\/code> <code class=\"plain\">VarbinaryTypeDescriptor.INSTANCE.getBinder( javaTypeDescriptor );<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">06.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">}<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">07.<\/code><span class=\"content\"><span class=\"block\">\u00a0<\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">08.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">return<\/code> <code class=\"keyword\">new<\/code> <code class=\"plain\">BasicBinder&lt;X&gt;( javaTypeDescriptor, <\/code><code class=\"keyword\">this<\/code> <code class=\"plain\">) {<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">09.<\/code><span class=\"content\"><span class=\"block\"><code class=\"color1\">@Override<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">10.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">protected<\/code> <code class=\"keyword\">void<\/code> <code class=\"plain\">doBind(PreparedStatement st, X value, <\/code><code class=\"keyword\">int<\/code> <code class=\"plain\">index, WrapperOptions options)<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">11.<\/code><span class=\"content\"><span class=\"block\"><code class=\"keyword\">throws<\/code> <code class=\"plain\">SQLException {<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">12.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">st.setObject( index, value, jdbcTypeCode );<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">13.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">}<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt2\"><code class=\"number\">14.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">};<\/code><\/span><\/span>\n<\/div>\n<div class=\"line alt1\"><code class=\"number\">15.<\/code><span class=\"content\"><span class=\"block\"><code class=\"plain\">}<\/code><\/span><\/span>\n<\/div>\n<\/div>\n<\/div>\n<p>Of course, we can probably somehow tweak this<code>SqlTypeDescriptorRegistry<\/code>\u00a0to create our own \u201cbinder\u201d, but then we\u2019re back to Hibernate-specific API. The fact is that the JPA 2.1 converter API is not going to be sufficient for these use-cases, as it doesn\u2019t allow you to specify how to interact with JDBC, which is often required.<\/p>\n<h2>Conclusion<\/h2>\n<p>Abstractions are leaky on all levels, even if they are deemed a \u201cstandard\u201d by the JCP. Standards are often a means of justifying an industry de-facto standard in hindsight (with some politics involved, of course). Let\u2019s not forget that Hibernate didn\u2019t start as a standard and massively revolutionised the way the standard-ish J2EE folks tended to think about persistence, 14 years ago.<\/p>\n<p>In this case we have:<\/p>\n<ul>\n<li>Oracle SQL, the actual implementation<\/li>\n<li>The SQL standard, which specifies\u00a0<code>DATE<\/code>\u00a0quite differently from Oracle<\/li>\n<li>ojdbc, which extends JDBC to allow for accessing Oracle features<\/li>\n<li>JDBC, which follows the SQL standard with respect to temporal types<\/li>\n<li>Hibernate, which offers proprietary API in order to access Oracle SQL and ojdbc features when binding variables<\/li>\n<li>JPA, which again follows the SQL standard and JDBC with respect to temporal types<\/li>\n<li><em>Your<\/em>\u00a0entity model<\/li>\n<\/ul>\n<p>As you can see, the actual implementation (Oracle SQL) leaked up right into your own entity model, either via Hibernate\u2019s\u00a0<code>UserType<\/code>, or via JPA\u2019s<code>Converter<\/code>. From then on, it will hopefully be shielded off from your application (until it won\u2019t), allowing you to forget about this nasty little Oracle SQL detail.<\/p>\n<p>Any way you turn it, if you want to solve real customer problems (i.e. the significant performance issue at hand), then you will need to resort to vendor-specific API from Oracle SQL, ojdbc, and Hibernate \u2013 instead of pretending that the SQL, JDBC, and JPA standards are the bottom line.<\/p>\n<p>But that\u2019s probably alright. For most projects, the resulting implementation-lockin is totally acceptable.<\/p>\n<div>\n<\/div>\n<\/div>\n<p><span class=\"acknowledgement\">Published at DZone with permission of <a href=\"http:\/\/java.dzone.com\/users\/lukasedergmailcom\">Lukas Eder<\/a>, author and DZone MVB. (<a href=\"http:\/\/blog.jooq.org\/2014\/12\/29\/leaky-abstractions-or-how-to-bind-oracle-date-correctly-with-hibernate\/\" target=\"_blank\">source<\/a>)<\/span><\/p>\n<p class=\"disclaimer\"><em>(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\ud558\uc774\ubc84\ub124\uc774\ud2b8 \uc0ac\uc6a9\uc2dc\uc5d0 \uc624\ub77c\ud074\uc5d0\uc11c \ub0a0\uc9dc \ud615\uc2dd\uc73c\ub85c \uc870\ud68c\uc2dc\uc5d0 Index \uc548\ud0c0\ub294 \ubb38\uc81c\uac00 \ubc1c\uc0dd.. &nbsp; \ub0b4\uc6a9\uc744 \uc694\uc57d\ud558\uba74.. \ud558\uc774\ubc84\ub124\uc774\ud2b8\uac00 \ub0a0\uc9dc \ud615\uc2dd\uc73c\ub85c \uc778\uc2dd \ubabb\ud558\uace0 \ud30c\ub77c\ubbf8\ud130 \uae30\uc900\uc73c\ub85c \ubb38\uc790 ( \ud544\ub4dc ) \uc640 \ub0a0\uc9dc ( \ud30c\ub77c\ubbf8\ud130)\ub77c \ud310\ub2e8 \ud558\uace0 \ud544\ub4dc\ub97c \ud568\uc218 \uc4b8\uc5b4\uc11c \ub0a0\uc9dc \ud615\uc2dd\uc73c\ub85c \ubcc0\uacbd \ud568.. \uadf8\ub798\uc11c \uc778\ub371\uc2a4 \ubabb \ud0d0.. \uacb0\ub860 \uc801\uc73c\ub85c \ud558\uc774\ubc84 \ub124\uc774\ud2b8\ud55c\ub370 \uc774 \ud544\ub4dc\uac00 \ub0a0\uc9dc \ud615\uc2dd\uc774\ub77c\ub294\uac78 \uc778\uc2dd \ud574\uc918\uc57c \ud568. What is the problem with Oracle DATE? The problem that was presented in the previous article is dealing with the fact that if a query uses filters on Oracle\u00a0DATE\u00a0columns: view source print? 1.\/\/ execute_at is of type DATE and there&#8217;s an index 2.PreparedStatement stmt = connection.prepareStatement( 3.&#8221;SELECT * &#8221; + 4.&#8221;FROM rentals &#8221; + 5.&#8221;WHERE rental_date &gt; ? AND rental_date &lt; ?&#8221;); \u2026 and we\u2019re using\u00a0java.sql.Timestamp\u00a0for our bind values: view source print? 1.stmt.setTimestamp(1, start); 2.stmt.setTimestamp(2, end); \u2026 then the execution plan will turn very bad with a FULL TABLE SCAN or perhaps an INDEX FULL SCAN, even if we should have gotten a regular INDEX RANGE SCAN. &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- | Id | Operation | Name | &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- | 0 | SELECT STATEMENT | | |* 1 | FILTER | | |* 2 | TABLE ACCESS FULL| RENTAL | &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- Predicate Information (identified by operation id): &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; 1 &#8211; filter(:1&lt;=:2) [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"ngg_post_thumbnail":0,"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[15,4],"tags":[],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p5q9Zn-8M","jetpack-related-posts":[{"id":74,"url":"https:\/\/blog.box.kr\/?p=74","url_meta":{"origin":544,"position":0},"title":"Logging\uc124\uc815 for JEUS5","date":"2014-06-12","format":false,"excerpt":"Logging\uc124\uc815 for JEUS5 \uc18c\uac1c \uc774 \ubb38\uc11c\ub294 JEUS 5\uc758 \uc6f9 \uad00\ub9ac\uc790\ub97c \uc0ac\uc6a9\ud55c logging \uc124\uc815 \ubc29\ubc95 \ubc0f customization \ubc29\ubc95, log4j \uc0ac\uc6a9\ubc95 \ub4f1\uc744 \uc124\uba85\ud55c\ub2e4. \uae30\ubcf8logger \ud30c\uc77c \ucd5c\ucd08 JEUS \uc124\uce58 \uc2dc, JEUS log\ub294 default\ub85c console handler\ub97c \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 JEUS manager\uc640 \ubaa8\ub4e0 engine container\uc758 log message\uac00 stdout\ud615\ud0dc\ub85c \ucd9c\ub825\ub41c\ub2e4. \ub610\ud55c web container \uc758 access log\uac00 $JEUS_HOME\/logs\/<\ub178\ub4dc\uba85>\/<\ub178\ub4dc\uba85>_<\ucee8\ud14c\uc774\ub108\uba85>\/servlet\/accesslog\/access.log\u2026","rel":"","context":"In &quot;JEUS &amp; WEBToB&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":619,"url":"https:\/\/blog.box.kr\/?p=619","url_meta":{"origin":544,"position":1},"title":"[\ud38c][IBM][CLI Driver] SQL0418N SQLSTATE=42610","date":"2015-03-13","format":false,"excerpt":"\uac1c\uad04 :\u00a0[IBM][CLI Driver] SQL0418N\u00a0SQLSTATE=42610 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\uba85\ub839\ubb38\uc5d0 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc740 \ub9e4\uac1c\ubcc0\uc218 \ud45c\uc2dc\ubb38\uc790\uac00 \uc0ac\uc6a9\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \uc6d0\uc778: \ub2e4\uc74c \uacbd\uc6b0\uc5d0\ub294 \uc720\ud615\uc774 \uc9c0\uc815\ub418\uc9c0 \uc54a\uc740 \ub9e4\uac1c\ubcc0\uc218 \ud45c\uc2dc\ubb38\uc790\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. SELECT \ubaa9\ub85d\uc5d0\uc11c \ub0a0\uc9dc \uc2dc\uac04 \uc0b0\uc220 \uc5f0\uc0b0\uc758 \uc720\uc77c\ud55c \uc778\uc218\ub85c \uacbd\uc6b0\uc5d0 \ub530\ub77c \uc2a4\uce7c\ub77c \ud568\uc218\uc758 \uc720\uc77c\ud55c \uc778\uc218\ub85c ORDER BY\uc808\uc5d0\uc11c \uc815\ub82c \ud0a4\ub85c \ub2e4\uc74c\uacfc \uac19\uc740 \uacbd\uc6b0 \ub9e4\uac1c\ubcc0\uc218 \ud45c\uc2dc\ubb38\uc790\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \uc900\ube44\ub41c \uba85\ub839\ubb38\uc774\u2026","rel":"","context":"In &quot;DB\uad00\ub828&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":257,"url":"https:\/\/blog.box.kr\/?p=257","url_meta":{"origin":544,"position":2},"title":"JQuery Ajax \ud1b5\uc2e0\uacfc Spring \uc778\uc218 \ucc98\ub9ac \ubc29\ubc95","date":"2014-07-24","format":false,"excerpt":"JQuery\uc758 Ajax\ud1b5\uc2e0\uc744 \ud558\uba74 \ud558\uae30\uc640 \uac19\uc774 \ubcf4\ub0b8\ub2e4. $.ajax({ type:\"POST\", url:'http:\/\/localhost:8180\/GisProject\/MainService', data:{mydata:JSON.stringify(params)}, datatype:\"json\", success:function(msg){ console.log(msg);}, error:function(xhr,status){ console.log(status);},}); \uc774 \uacbd\uc6b0 \u00a0Spring \uc758 \uae30\ubcf8 Parameter\ub85c\ub294 \ubc1b\uc744 \ubc29\ubc95\uc774 \uc5c6\ub2e4.. \uc65c \ub0d0\uba74. Requert.payload \ud615\uc2dd\uc73c\ub85c \ub118\uc5b4 \uac00\uae30 \ub54c\ubb38\uc5d0.. \u00a0 \uc774\ub97c \ubc1b\uae30 \uc704\ud574\uc120 \ud558\uae30\uc640 \uac19\uc740 \ucc98\ub9ac\uac00 \ud544\uc694 \ud558\ub2e4.. \/\/ Request playload Data \uac00\uc838\uc624\uae30. BufferedReader bfr= req.getReader(); \u00a0\/\/ getReader\ub97c\u2026","rel":"","context":"In &quot;JAVA&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1139,"url":"https:\/\/blog.box.kr\/?p=1139","url_meta":{"origin":544,"position":3},"title":"JQuery with Bootstrap","date":"2016-07-27","format":false,"excerpt":"http:\/\/maczniak.github.io\/bootstrap\/javascript.html \u00a0 and \u00a0 Collapse navigator \u00a0 http:\/\/zetawiki.com\/wiki\/%EB%B6%80%ED%8A%B8%EC%8A%A4%ED%8A%B8%EB%9E%A9_%EB%82%B4%EB%B9%84%EA%B2%8C%EC%9D%B4%EC%85%98%EB%B0%94_%EC%9E%90%EB%8F%99%EC%A0%91%EA%B8%B0_navbar-collapse \u00a0 \ubaa9\ucc28 1 \uac1c\uc694 2 \uc608\uc2dc 3 \uac19\uc774 \ubcf4\uae30 4 \ucc38\uace0 \uc790\ub8cc \uac1c\uc694[\ud3b8\uc9d1] Collapsing The Navigation Bar, navbar-collapse \ubd80\ud2b8\uc2a4\ud2b8\ub7a9 \ub124\ube44\uac8c\uc774\uc158\ubc14 \uc790\ub3d9\uc811\uae30 \uc608\uc2dc[\ud3b8\uc9d1] \ud654\uba74\ub108\ube44\uac00 \ub113\uc73c\uba74 navbar-collapse\uc774 \ud45c\uc2dc\ub418\uace0, navbar-toggle\uc740 \uc228\uaca8\uc9d0 \ud654\uba74\ub108\ube44\uac00 \uc791\uc73c\uba74 navbar-collapse\uc740 \uc228\uaca8\uc9c0\uace0, navbar-toggle\uc740 \ud45c\uc2dc\ub428 \ub300\uc2e0 \ubc84\ud2bc\uc744 \ub204\ub974\uba74 \uc138\ub85c \ub4dc\ub86d\ub2e4\uc6b4 \ud615\uc2dd\uc73c\ub85c \ub098\ud0c0\ub0a8 http:\/\/zetawiki.com\/ex\/bootstrap\/navbar-collapse.html\u2026","rel":"","context":"Similar post","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":61,"url":"https:\/\/blog.box.kr\/?p=61","url_meta":{"origin":544,"position":4},"title":"WebtoB + JEUS + web application","date":"2014-06-12","format":false,"excerpt":"WebtoB + JEUS + web application webgosu.egloos.com\/9123240 1. WebtoB \uc124\uce58 1.1 \uc124\uce58\ud30c\uc77c, \ub77c\uc774\uc13c\uc2a4(license.dat)\uc900\ube44 1.2 \ub77c\uc774\uc13c\uc2a4 \uc801\uc6a9 : webtoB4.1licenselicense.dat 2. WebToB \uc2e4\ud589 2.1 \uc2e4\ud589\ud30c\uc77c\uc0dd\uc131(wsconfig) --> \ud658\uacbd\ud30c\uc77c \ucef4\ud30c\uc77c : wscfl -i [\ud658\uacbd\ud30c\uc77c] 2.2 \uc2e4\ud589 : wsboot --> wsboot -w (handler\uac00 process\ub4e4\uc744 \ud655\uc778\ud558\uba70 booting->\uc548\uc815\uc801\uc778 booting) 2.3 \uc885\ub8cc : wsdown --> wsdown -i (\uc9c8\uc758\ub97c\u2026","rel":"","context":"In &quot;JEUS &amp; WEBToB&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":385,"url":"https:\/\/blog.box.kr\/?p=385","url_meta":{"origin":544,"position":5},"title":"[\ud38c]iBatis \ub85c\uadf8\ubcf4\uae30 &#8211; log4j \uc124\uc815","date":"2014-09-15","format":false,"excerpt":"iBatis \ub85c\uadf8\ubcf4\uae30 - log4j \uc124\uc815\u00a0iBatis \uc791\uc131\uc2dc\uac04 :\u00a02010\/02\/04 15:51 \ud37c\uba38\ub9c1\ud06c :\u00a0slog2.egloos.com\/3574039 \ub367\uae00\uc218 :\u00a01 \ucc38\uace0\uc790\ub8cc :\u00a0http:\/\/ibatis.apache.org\/\u00a0- for Java - Documentation - Korean\u00a0 \u00a0 \uc774 \uae00\uacfc \u00a0PDF \ucca8\ubd80\ud30c\uc77c\uc744 \uac19\uc774 \ubcf4\uc2dc\uae30\ub97c..\u00a0Log4jQuickRef.pdf\u00a0\u00a0 \u00a0 \u00a0 1. log4j \uc124\uce58 \u00a0 http:\/\/www.apache.org\/ \u00a0- Logging - log4j 1.2 - Download - apache-log4j-1.2.15.zip\u00a0 \ud30c\uc77c\uc744 \ubc1b\uc544 \uc555\ucd95\ud480\uc5b4\u00a0JAR \ud30c\uc77c(log4j-1.2.15.jar)\uc744 \u00a0\ud504\ub85c\uc81d\ud2b8\uc758 WEB-INFlib \ud3f4\ub354\uc5d0\u2026","rel":"","context":"In &quot;\ucc38\uace0\ub97c \uc704\ud55c \uc800\uc7a5\ubb3c&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/blog.box.kr\/index.php?rest_route=\/wp\/v2\/posts\/544"}],"collection":[{"href":"https:\/\/blog.box.kr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.box.kr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.box.kr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.box.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=544"}],"version-history":[{"count":0,"href":"https:\/\/blog.box.kr\/index.php?rest_route=\/wp\/v2\/posts\/544\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.box.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=544"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.box.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=544"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.box.kr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=544"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}