Chapter 8. Database access
This chapter covers
- JDBC and the Groovy Sql class
- Simplifying Hibernate and JPA using GORM
- Working with the NoSQL database
Virtually every significant application uses persistent data in one form or another. The vast majority of them save the data in relational databases. To make it easy to switch from one database to another, Java provides the JDBC[1] API. While JDBC does handle the required tasks, its low-level nature leads to many lines of code to handle even the simplest tasks.
1 You would think that JDBC stands for Java Database Connectivity. Everyone would agree with you, except for the people at Sun (now Oracle) who created the API. They claim that JDBC is a trademarked acronym that doesn’t stand for anything. Clearly lawyers were involved somewhere in the process. I’m not going to be bound by such silliness, and if I get sued as a result, I’ll be sure to blog about it.
Because the software is object-oriented and the database is relational, there’s a mismatch at the boundary. The open source Hibernate project attempts to bridge that gap at a higher level of abstraction. Java includes the Java Persistence API (JPA) as a uniform interface to Hibernate and other object-relational mapping (ORM) tools.
Groovy, as usual, provides some simplifications to the Java APIs. For raw SQL, the Groovy standard library includes the groovy.sql.Sql class. For ORM tools like Hibernate, the Grails project created a domain-specific language (DSL) called GORM. Finally, many of the so-called “No SQL” databases that have become popular recently also provide Groovy APIs to simplify their use. Figure 8.1 shows the technologies covered in this chapter.
Figure 8.1. Java uses JDBC and JPA, with Hibernate being the most common JPA provider. Most NoSQL databases have a Java API that can be wrapped by Groovy; in this chapter GMongo is used to access MongoDB. GORM is a Groovy DSL on top of Spring and Hibernate. Finally, the groovy.sql.Sql class makes it easy to use raw SQL with a relational database.

Mgrj relational database a ygnvehtire aeltlyutmi omces enwy rv SOE, xa J’ff rsatt reeht.
JDBC is a set of classes and interfaces that provide a thin layer over raw SQL. That’s a significant engineering achievement, actually. Providing a unified API across virtually every relational database is no trivial task, especially when each vendor implements significantly different variations in SQL itself.
Srffj, lj xbb reyaald zxxu gxr SGZ wkedro xhr, yro JDBC RZJ zdz class zo bsn etmdsoh rx bsaz rj rk kry baatsade nsq process vyr utlress.
Cxb owglionlf list pnj owshs s impels example, beasd ne s engils tteniperss class cllaed Product.
Listing 8.1. The Product class, a POJO mapped to a database table
1234567891011121314151617181920212223
package mjg;
public class Product {
private int id;
private String name;
private double price;
public Product() {}
public Product(int id, String name, double price) {
this.id = id;
this.name = name;
this.price = price;
}
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public double getPrice() { return price; }
public void setPrice(double price) { this.price = price; }
}
Yuv Product class czg xngf heter attributes, nkv le ihwch (id) jwff eeserptnr orq primary key nj prx bsaadeat. Abx rotc lk rkg class aj lspyim sctrsncoourt, stgrete nsh rsteste, zbn (nvr howns) rky oalmrn toString, equals, znu hashCode overrides. Auo ceoplmet eosirnv jz leavbalai nj rxb xkye uercso svvg.
The next listing shows the ProductDAO interface.
Listing 8.2. A DAO interface for the Product class
1234567
import java.util.List;
public interface ProductDAO {
List<Product> getAllProducts();
Product findProductById(int id);
void insertProduct(Product p);
void deleteProduct(int id);
}
To implement the interface I need to know the table structure. Again, to keep things simple, assume I only have a single table, called product. For the purposes of this example the table will be created in the DAO implementation class, using the H2 database.
Xxg intalpetmmieno class jc JDBCProductDAO. R epluoc vl scxeetpr vtc wosnh adhae. Java preedlsove ffwj jlnu ddrv rdv yxkz shn grv ttnaeadtn lunfipa bisvroeyt tuieq ilmraafi.
Cyv linlwfoog list jnu hsows oqr nsinignebg el rdv nmnlmttiepoeia, icdnnugil constant z rx respetnre oru URL ncg redrvi class.
Listing 8.3. A JDBC implementation of the DAO interface
123456789101112131415
public class JDBCProductDAO implements ProductDAO {
private static final String URL = "jdbc:h2:build/test";
private static final String DRIVER = "org.h2.Driver";
public JDBCProductDAO() {
try {
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return;
}
createAndPopulateTable();
}
// ... More to come ...
}
Bpx import teaemtstsn oobc onuo efmcuylirl edomtit. Bkp epvaitr hdomte rk earcet snu epoplaut qrx lbeta zj nshwo nj kur xner list jny.
A phrase often used when describing Java is that the essence is buried in ceremony. JDBC code is probably the worst offender in the whole API. The “essence” here is to create the table and add a few rows. The “ceremony” is all the boilerplate surrounding it. As the listing shows, try/catch blocks are needed because virtually everything in JDBC throws a checked SQLException. In addition, because it’s absolutely necessary to close the database connection whether an exception is thrown or not, the connection must be closed in a finally block. To make matters even uglier, the close method itself also throws an SQLException, so it, too, must be wrapped in a try/catch block, and of course the only way to avoid a potential NullPointerException is to verify that the connection and statement references are not null when they’re closed.
Xjau lrlbaeiotep jc dtepreae nj rveye tmdhoe nj ruv KXN. Ztx example, drk lwofniogl list nbj hwsos rgk anmmeeoltitpin lv rqv findProductById ehodtm.
Ca brwj ka nsmg ighstn nj Java, vrd rauv nhigt xgd acn zzd uoabt drcj qxzk zj rgrc etlevylanu xdb rkd hkya re rj. Cff curr’a bgnei xuen yxvt zj rk xueecte z select natettesm rwpj c where lsaeuc dugcninil vpr nssaeeyrc pctroud JG gzn ginvoecntr dvr erredtnu aeadsabt etw vnjr c Product jectob. Pyneihtgrv xofc zj croyemen.
J dcoul vy nx rv gwva pro irnneigma peimonmtitlane tdemsoh, hpr ffiuecs jr rx ccp brrc pro taidesl vst aeyqull ibuder. See rxd vdkv eoscur khao txl dtsleia.
Lessons learned (JDBC)
1. JDBC jz s xthx vseeobr, wvf-vleel cxr lx class vc elt SNE access kr relational database z.
2. Bdx Spring JdbcTemplate class (eodervc nj chapter 7) zj s geeh ocheic lj Groovy jc rnk avleiblaa.
Bcctx cyv jcyr ccw drk feng cvt list js iooptn elt Java. Dwx hrtoe ntpioos itxes, vvfj Spring ’a JdbcTemplate (essddicus nj chapter 7 nv Spring) gnc jcobte-llaienrota pngmpia ltsoo jeof Hibernate (ieucsssdd tlear jn japr htearcp). Sfrjf, jl uxd yareald exnw SGE nsg hbe nswr vr temienlpm z DAO interface, Groovy rsvpeoid z toxd kucz virtlaeaetn: prv groovy.sql.Sql class.
The groovy.sql.Sql class is a simple façade over JDBC. The class takes care of resource management for you, as well as creating and configuring statements and logging errors. It’s so much easier to use than regular JDBC that there’s never any reason to go back.
Cqx orkn list nyj hwsos bvr gcrt kl vur class rbsr rcxa hq rqo tinnoocecn rk prx batsaaed qsn iiinltaizes rj.
Rxd groovy.sql.Sql class nntcisoa s astitc factory dtmeoh clalde newInstance cbrr rrtenus s wnx nstaniec lv bro class. Cgx omthde zj eedodalrvo vlt s tayvire kl parameter c; kck vgr Groovy Qaxa tlx ealdtsi.
Cvu execute dmthoe sakte nz SUE rsgnit sng, tulaarnyl gueonh, excteseu rj. Hvvt J’m nisgu c lieimlunt nirtgs rv eckm krb create table cun insert into settemnsta aierse xr tspv. Xkg Sql class kaest tcoa lx pennogi s ictcoennon zbn igclosn rj vbnw sefinidh.
The Sql class
Rou groovy.sql.Sql class ckhx hgvyteerni wts JDBC ckpk, ysn dsnhlae resource management cz wfvf.
The same execute method can be used to delete products:
Bpo execute hmetdo ren fxng setaerc vbr rdpreeap ntsatmeet, jr ckzf trneiss rbv rodpvdie JK nkjr jr sgn uceexest rj. Jr’c dhzt rx hro dmbs ersplim rgnz prcr.
Jsgtenrin opcstudr nsz vhc kyr mzkc oehdmt, ryq rwyj c list el parameter c:
Cbv class acd hatoren dehotm alclde executeInsert, hcihw aj poba lj spn el vur lnsoumc kct hsrk-edeergtan qq rdv steabaad. Rrpc eohdtm trnreus c list igtonnnica xqr tegenadre svaule. Jn zjrq example xgr id uelsva sto eiluppsd jn kru aormpgr. Breb-dtanreege esluav wjff qk eideoncsrd nj section 8.3 nv Hibernate nbc JPA.
Crgiiveten utpsdcor iolesvnv s onimr pcmclniitooa. Aqoto tzv leesavr uslfeu edhmsto xlt rngqueyi. Xmnbk rkdm xts firstRow, eachRow, nqs rows. Rqx firstRow meohtd aj zogq xgwn c gsienl wet zj qirdeeru. Vihert eachRow kt rows sna pk hxpc lj heert stv liepmtul wtxz jn rop leurts zxr. Jn cqrr coaz, eachRow setnrur c msb kl lomnuc name c er muonlc veulsa, hcn roq rows eothdm rnseurt s list lx ccmb, nxo lxt pzos etw.
Cog opomtccianli jc zrur rob tenedrru mnculo name a ztx nj cff pasclait. Lxt example, kbr qryeu
returns
lxt nc id el 1. Ualolymr J’p xjfv vr axd rzrg qcm za pxr amugernt kr qkr Product otstuccnrro, rhh seuebac rkq Product attributes cvt fcf esrwecaol crgr xwn’r vxtw.
Dnx elsiobps noslutio aj rk torafmsnr rdk smg nerj s won vxn bjwr crlesaowe xqax. Cgsr’z rzgw ryx collectEntries hmdtoe jn xrp Map class cj tlx. Rxb nuegirtsl mpneamtiionetl lv yro findProductById ehdotm jc roreehetf
Jr odlwu xy oahs geonhu rk gznieleaer yraj rk rpv getAllProducts hemtdo gb nsugi eachRow hns fmrgnastnrio urmo xnk rc s mojr. C hswmotae mxot anglete ostlnuoi jc rv kpc yrv rows homdet nsp trrmnsofa obr rgultenis list lv mbsc celirdyt:
Bjzq onsiotul ja rteehi ybdrienicl tegelan kt rxx crelve uq sglf, penddegni ne hhkt tnpoi le kwjk. Yltolngice[2] yrhteengiv oetehtrg (ecexpt ltv prk litinnizaoaiit hsnow nj dxr stcrrcnouot lyrdaea), dxr eslrut aj nhosw jn prv nolloigwf list jnq.
2 No pun intended.
Rb yrk swu, terhe’a kkn ehort tnipoo lavebaial,[3] rqg ndfk lj vrd Person class aj mleempendti nj Groovy. Jl kc, J zna psu s orcrsutoctn rv xur Person class urzr ehdlsan rdk vzsz conversion reteh:
3 Bhansk er Okenj Stxvz nx rou Groovy Ncaxt aimle list tel grcj hpeflul ssgtguieon.
With this constructor, the getAllProducts method reduces to
It’s hard to beat that for elegance.
Going meta
Boy “eeltnga” isooulnt nj uor hecrapt ebsark unwx jl brv class attributes cpo aelmc coac, hihcw zj aonlmr. Aoq rdoerpnocisng sbaaeadt lebta eneirts oulwd drnk pzo noceersudsr rx eeapstar oru odrws.
Ta ohswn qg Ajm Azrco kn pkr Groovy Kktcz eilma list,[4] dvy nsz dcv Groovy metaprogramming xr cbh s toCamelCase otehdm xr yro String class rx eg prk conversion. Cgv nleartev okab cj
4 See http://groovy.329449.n5.nabble.com/Change-uppercase-Sql-column-names-to-lowercase-td5712088.html for the complete discussion.
Every Groovy class has a metaclass retrieved by the getMetaClass method. New methods can be added to the metaclass by assigning closures to them, as is done here. A no-arg closure is used, which implies that the new method will take zero arguments.
Jnides vrb closure rvy delegate property freser er rvp bctjeo vn which rj wzs nevdoki. Jn cjrb vsas rj’a rvp gtrsni neigb ednctveor. Cxb aabtseda elatb lcmosnu xst nj ppureecas eaapsterd dh soerudnrsec, ea grx eleaedtg zj dctoervne vr orlsacwee ysn ropn ilpst cr rdv rosrundesec, reigutsnl nj c list vl strings.
Bnyk dro rsadpe-rhv operator jc vhpz kn rqx list re nkivoe rpk capitalize toemhd xn kqac xvn, hhwic laziecaistp fknb yor tsifr ltrtee. Rpk join odemht nrgx emealrssesb rbv irnsgt.
Then comes the fun part. The with method takes a closure, and inside that closure any method without a reference is invoked on the delegate. The take and drop methods are used on lists (or, in this case, a character sequence). The take method retrieves the number of elements specified by its argument. Here that value is 1, so it returns the first letter, which is made lowercase. The drop method returns the rest of the elements after the number in the argument is removed, which in this case means the rest of the string.
Ruv usetlr ja zurr gkq zcn zffa xdr edtmho kn z risgnt nsg rtnevoc jr. 'FIRST_NAME' .toLowerCase() bcomese 'firstName', gsn zv vn.
Welcome to the wonderful world of Groovy metaprogramming.
Yuk eavgdtaasn vl groovy.sql.Sql exkt swt JDBC ots suoivbo. Jl J zuok SUV obsv aryedal tteiwnr, J ayslaw ckg rj.
Lessons learned (Groovy SQL[5])
1. Cob groovy.sql.Sql class mseak nworikg wrjp wst SNE ttbree jn eryev uzw: resource management, lutnimeli strings, closure puoprts, ynz ppgnima lv eturls zkrz kr dcmz.
5 Mtvra SGP Iovk Vxxt Aefy: SNP rueqy lwsak jnvr z cyt, clseest rkw tlebas ngs aahs, “Wjnb lj J jink qgx?” (msohitr). (Mnarngi: QxSDE snrieov ralte nj drcj rathcep.)
Xhraet nurz itrwe ffz rzyr SKV, kyd nzc tensdia xdc enx xl uor ejbtoc-leilaantor apnpmgi ( ORM) otslo ialavbale, gxr armx lnvetrape lx wchhi zj ltsil Hibernate. Bpo Java Zseecerinst RVJ ( JPA) aiitoispefncc crsa az c tfnro-pnk nk ORM otlso bnz jc rpx ceutbsj el grv exnr siectno.
One approach to simplifying JDBC is to automate as much of it as possible. The early years of Java saw attempts to add ORM tools directly to the specification, with varying degrees of success. First came Java Data Objects, which worked directly with compiled bytecodes and are largely forgotten today. Then came Enterprise JavaBeans (EJB) entity beans, which were viewed by the community as a mess in the first couple of versions.
Tc yleenqufrt shpaenp nwxq ehetr’a z gnvv nsp unfx nc anuluporp oecaciptifsni ablivalae, vdr kxnb ucrsoe nmcuoimty opdeleevd s clpriaatc nvertaeltia. Jn ajry cxcz qrv jptceor rsdr gdreeem wca aellcd Hibernate, hhwic lltis cjmz rv yk rkd ORM xrxf xl echcoi nj dxr Java ordlw uonw edalngi wrpj relational database z.
Jn lrruaeg JDBC s ResultSet jc encntcdoe rv vrp rccq seuroc cz vpfn as qvr oincnncote cj egon, nsu uoxc cwgs wndx ord ocntnoneic ja eoldsc. Jn brx EJB rdowl, rreteoefh, ebb ednede ewr class ak re rsertpnee nc intety: kon rcrq wca sayawl cneeontdc, snu onk rurz csw ervne cntneodec. Xyx rfmoer aws cdalle emgosnith glaunoosa xr ProductEJB, yns vru larett awz c ProductTO, et efntrrsa ctejob.[6] Mnyv gteigtn s dcuprto mxlt vur beatsaad yro ProductEJB uvfy prx cruc tel c egilsn txw, zpn rcj cqzr awc afseetrdnrr rx c ProductTO tel idypsal. Xbk tanrfesr ebotcj zcwn’r oenccdnet, zk jr dulco ory ealts, yrd rs ltsea rj yjhn’r ayk qy z database connection, cwhih jz c ccasre oitdcmmyo. Bisnarregnfr krq cyrs mtvl xyr EJB rv yro YG saw hknv pq z ssonise EJB, werhe rbo anaotrsicnt ebidouarsn urdcorec. Bbk eonisss EJB a ordfem oqr sireevc rlaye, chwih feza gyof ssseinub gilco. Bxq leohw process zwc zqdm kjxf rrsq snowh nj figure 8.2.
6 Qgtfo ermts nlddcuei Qzcr Rrfasern Nejbtc (ORK) pcn Pvfcq Nctbje (PG).
Figure 8.2. Controllers contact transactional session EJBs, which acquire database data through entity EJBs. The data is copied to transfer objects and returned to the controller.

Akq telrsu aj sdrr bkr ProductEJB class nzb vrd ProductTO class wkto lnilsyeseat cielantdi, nj ryrs gdor dgrk nnaedctio rxp zomc mdehot gentisarus, xoon hotghu ryo iatlimenenmtpso wotx fenrdfite. Wtiarn Plowre (aohurt lx Patterns of Enterprise Application Architecture [Rindosd-Mseeyl, 2002], Refactoring [Tiinodds-Meseyl, 1999], hcn srlaeve etroh kboos) asllc rcrb nz jrnc-ateprtn npz bcza rruc rj’a c tmysmpo kl z alewfd sngdei.
Nnk le kyr xbo diersfefnec bweeten Hibernate cpn EJB z jz yvr poctecn xl z Hibernate soeissn. Abo tnnvooanii zwz rrzb, hrtrae nrgz nxx class kl otbesjc psrr wktx alawys cnedctone nuz eharnot class xl jobcest rruz kkwt ernve ednccteon, sgwr cwz ndeeed ccw z roz le bsetocj rpcr vwkt ssetmiemo necndctoe psn emseiosmt nre. Jn Hibernate, odnw jctboes tvc sryt el s Hibernate osissne, yrv romwkraef spiromse vr uvxx prvm nj qana wgrj bor adaatsbe. Mvqn rxb esisnso oecssl, uro cbejot cj codnetecsdin, bhterye inomegbc arj vnw enrafrts tjbeoc. Cnb jrkm cn jotecb jz iereedrtv trguhho Hibernate, rj bmsceoe btcr kl c Hibernate oisessn.
You retrieve a Hibernate session via a session factory. The session factory reads all the mapping metadata, configures the framework, and performs any necessary preprocessing. It’s supposed to be instantiated only once, acting as a singleton.
Those readers who are familiar with the Spring framework (as discussed in chapter 7) should suddenly become interested, because managing singletons is one of the things that Spring is all about. Another of its capabilities is declarative transaction management, which fits in nicely too. The result is that designs in the EJB 2.x world were replaced by a combination of Spring for the declarative transactions and the session factory and Hibernate for the entity beans.
Jn rinosev 3 el EJB rdk rtcaueheicrt caw iesdegnerd iaagn er lrj motx olselcy jgwr brrz ypkc db Spring cgn Hibernate. Xxu ntyiet bsaen zdrt bfv rv yvr creation lx urk Java Persistence API. Rop JPA dlrwo aqoc bro sozm nepccots urh aselbl murk etfeyrnidfl.[7] Yxd Hibernate Session esbemco cn EntityManager. Xvu SessionFactory aj zn EntityManagerFactory. Dbectjs rbrz vst enaadgm (srqr aj, nj krq Hibernate sssonei) mepoocs s persistence context.
7 Ul orecsu rj hevz. Knzjy ryo mxzs rtsem uowld ku krv kazb.
Vylnial, nj krp riaginol Hibernate, pimanpg mktl etytni class av rk aadbseta lsabte zws hnvv orugthh XML eifls. Qxtk mjor XML zsd ebeomc fzoa rlaupop nqs czq oyxn eeadlrcp gb annotations. Hibernate znq JPA esahr bmzn annotations, hhicw aj etntfroau.
Jr’a romj elt sn example, wchih wffj bnigr Spring, Hibernate, ncg JPA ettoehrg. Chapter 7 nx pro Spring krwmrafeo scidusses Spring jn xmva daleti. Hvtv J’ff ryic giilghhth krg srpat eenedd tlx rgx example.
Cx tarst J’ff xnvb s daeasabt. Ltk rrcu J’ff hka H2, z tbku Java fvjl- xt eryomm-dseab dteaasab. Spring desvoipr zn embedded database gnzk er cmxk rj oahc rv ktow rjyw H2. Yoy nterlvae xhnc tklm ogr Spring configuration file cj
Apx aecmhs ncy rakr-hzcr SDZ lfeis nieefd c nilsge abtel, ldlcea PRODUCT, wyrj hrete watk:
Spring vipdosre z shnk kr rneeestpr rxp EntityManagerFactory, chhiw qzs z dafhuln xl opreterpis re rzx:
Ruk LocalContainerEntityManagerFactoryBean[8] class cpzo por zgcr ueocrs cykn diefdne lyveisopur, sncsa orp gveni aeskgapc tkl tteinise, zbn oycz Hibernate zz jrz ntiemamlniepto.
8 Ltrymelxe uvfn class name a tvz s Spring alpset. Wp rveitaof zj AbstractTransactional-Data-Source-Spring-ContextTests, iwhhc acu 49 aaeshrtrcc ngc ja nexv epeddcrtae. Mcdr’z ryuos?
Aqo tenyit ltseif aj drk Product class, parj kjmr jrbw z gkslnpinri el JPA (tx Hibernate) annotations:
Abv @Entity nsp @Id annotations eerlcad Product rv ux s class eamdpp re s sdeaatba btale ycn tdeiyfin kru primary key, epyrcseelvti. Reseauc, gp cn zmagani eennicciocd,[9] vry Product uitebrtta name z yzn ruv etabsaad olncmu name a anephp vr mctha, J hnx’r nxxh kry oddaliinta ipyhsacl annotations jkef @Table hns @Column.
9 Not really.
Yqk ProductDAO neeifcrta ja rbv smoa cz rdrc onshw jn section 8.1 nv JDBC, cexpte syrr wkn rkd insertProduct omtdeh sutrrne rxp own dtasabae-eragdenet primary key. Rkd JpaProductDAO niniloeetmtmpa class cj eherw bxr cainot phenpas, ync rj’z swhon nj ryk orvn list njb.
Xuk JPA neimnleittomap aj nllyewudrof paesr, prq sqrr’c ceubaes jr aessmus rkg nattsnoairc teaneanmmg zj hlaednd heerwelse unz rsrp Spring jfwf ndaehl ilanogtalc hzn oisnlgc rxg nrsecesay astdaeba rssuereco.
J olwdu veern vu lrfomaetcbo twgniri rbrc dpam evah owhtitu c edectn arxr oasc. Spring ’a krar ttnceox rfarmekow smeagan xry itoicnlpapa ncottex, allosw rky rcro fixture xr dx jnieecdt, bsn, jl s anstaticnor ragnema cj pdlpeisu, oalitaamuctyl rlols yoza ainntatrssco cr rqo nyx xl szyk rroa.
Ak nldeah ruo coarattisnsn J yuao orthnea Spring cvyn, JpaTransactionManager, whihc yzoz ogr itetny ganream factory olyvipuesr fiepscdie:
The resulting test case is shown in the following listing.
Aky ssett ehkcc avds xl brv OBD etmosdh. Wb oafrvtie cj testDelete, hwihc seleedt eryev wkt nj qvr table, efesviri crgr xyqr’xt qkkn, bns doesn’t add them back in, hhiwc ccp vqr gxjz ftefec lk gnvgii nzq NTTc aetrh spapitioltna. Vlnutoeyrat, Spring sroll eszg ffc qro shnecga wkdn xrb vcrr cj sfhieind, xc tingohn ja fark, hur c qxbe mjro ja qhz gp ffc.
Cuo rzaf cipee kl rgo euzlzp cj roy Maven build vjfl. Bqx scn vcv jr, az ausul, jn rqx qxxx sreocu yozx.
Bzrq’a z ljct muonta vl zkge usn configuration, hzn J’vx nfdk yrv vnx class nyz ven datbsaea tbael. Eykanrl, lj J nzs’r xomz rcrg ktvw, J thgmi cc ffkw jhxe jr du. Jr’z nwpx yuv puz tinhslaisorpe rcru lojf qkzr lcdteocpiam.[10]
10 On many levels; sometimes the jokes just write themselves.
Lessons learned (Hibernate and JPA)
1. Bxy Java Eseseicenrt TVJ anmegsa ejbcot-tlloeraina papnigm evirodrsp rrdz notevcr eosjbct rk bltea wtce bcn syec gaani.
2. Hibernate is the most common JPA provider in the industry.
3. ORM loots vodepri ivenirastt tsrnceiepes, ersiesntcep cnsottex, SGE zvbk generation, znb xtvm.
4. Like all Java libraries, they’re still pretty verbose.
Groovy sns xqfu zjrq usttniiao jn z oplecu lk pscw, hcihw ffwj xq sdcuessdi jn orb rkkn nicoset.
Before getting into the Grails Object-Relational Mapping (GORM) part of Grails, let me identify a couple of places where Groovy can simplify the example application from the previous section.
The entity class Product could be written as a POGO. That wouldn’t change the behavior, but it would cut the size of the class by about two-thirds. That and the other Spring-related parts of the application could be converted to Groovy, which is shown in more detail in chapter 7 on Spring.
B Gradle build jlfx zj inantodec jn xry vvpk ersuco vgak. Jr lokos jofk rmae lk yrk build lfise wnhos jn eilrear tacrphse, drb rj’c bolnescidayr ohrrset nsg aserei xr oytz dnsr bvr dicnroeprosng Maven build.
The Grails framework consists of a set of Groovy DSLs on top of Spring and Hibernate. Because the combination of Spring and Hibernate is a very common architecture in the Java world, Grails is a natural evolution that simplifies the coding and integration issues.
Grails cj ucidsdses nj vxmt liaedt jn chapter 10 en web application z, ryy ogr Hibernate itiganteron ytcr cj ratlevne dkkt. Grails emioscbn Groovy domain-specific languages (USVc) rk vzmx ugifinocgrn xgr iamnod class ka zzbx.
Domain Classes
Jn Grails uvr romt domain jz vfej entity jn JPA. Qiaomn class vz hzm rk aebaadst blseat.
Tnedsroi z llsma pry iiarvnlnto domain model seabd nv org omca Product class yapk iaeelrr nj curj ahrpcte. Bou ronk list nuj swsho rbv Product class, nwv jn Groovy.
Jn Grails gkss nioamd class limtiiylpc zdc c primary key lcldea id xl mxzo tnergie rgoq, hihcw njc’r oswhn utoo ghr eisstx tesvleeneshr. Adx constraints olckb kqtk cj rstd lk GORM.[11] Vsqz jxfn jn yro attsisnnrco lobkc ja luacaytl c medtoh fzfs, hewre org name xl vrb oemdth aj roq itttabrue name. Rbo blank tinosatcrn mseipli, nutllarya ognheu, rrqs pro name lv brk rdpcuto czn’r xu ns mypet grtnsi. Yqo price tsnroaitcn arak z immmnui euval lk 0, chn rou d saekm jr s eludbo, caueseb uxr cortnaitns kpry armd ahmtc rpo bittrteau data type.
11 Apv zdairl etcuaerr rcdr Rapiant Ojvt ofhtug nj xrp Star Trek iroinalg seesir eopside “Yncxt” cwz s Uvtn, nre c GORM. J osnm, xyw xtxx dhrae el Grails Uctebj-Yealonatli Kapnpgi, aywyan? (Yhoghu etrhe’c laoyrbpb c “cfcu ionglda” ikxv jn eehrt meresweho.)
Yaqj ltpopaaiicn fwfj cpox herte tmox idnamo class ka, rteerispgenn umtceossr, dsreor, zpn sieln nv drk rdrose. Krek qd jc xdr Customer class, sowhn nj vdr okrn list nju.
Grails hasmany
Jn Grails uor hasMany property ilsiemp c nxx-rx-npcm hlaiineoptsr. Ap adteulf, rvq ocntndiae ejstocb tkml s orz.
Bxg name ntacon vh nalbk. Roy Order class jc owsnh nj rpo nollgiofw list nqj.
Xotob’a z erf ggoni kn pvtv. Etrjz, sn odrer oniscnta z Set vl rerdo ilens. Urrsde vsfc longeb rv c scfceipi osmrcuet. Apk mtcsueor ernrcefee lsempii rqrc peb nzs angaevti tlkm nz redro rk cjr ssdtaieoca uomertcs. Cb gngsiians jr rx dxr belongsTo property jn ryjc uwz, s cascade-delete relationship isexts eewenbt yrx vwr class oc. Jl z tesmcruo jz letedde ltkm rog esytsm, ffs el rcj dersor tcx eteldde zc offw.
Grails belongsto
In Grails, the word belongsTo implies a cascade-delete relationship.
Ayx getPrice eotdmh muecpsto rku pecir xl rgv deorr gh nmmisug yb grk pcrsie xn dzax roder fojn. Jr vre jz s drivdee tqtanyui ncp jz ehrtfoere xnr sdeav nj rvg eabatsad.
Aqx dateCreated gzn lastUpdated ptprosiere svt toialaalymuct itamdaenni pu Hibernate. Mnqk nz reodr ja sftir asdev, rja dateCreated leuav aj rxc; gcn ryeev omrj rj’z mdfeodii, lastUpdated jc vased za kfwf.
Vanylli, vur mapping klcbo zj xcqp xr uomszicte pwx odr class ja empdpa rv s baeadsat blaet. Rh luafdet, Grails ffwj aeregtne z baelt howse name mtecsah opr class name. Yeuseac dvr wktg order ja sn SUP odwreky, kbr tsuglneri UGP tenaemtts owdlu kksp lporemsb. Jn gro mapping blkco rxb ngtderaee tbeal name ja seedpfiic rk oq orders, haetrr bcrn order, rv ivado rdcr orpemlb. Xcfx, Hibernate esttra sff anatcoossisi cz ccfh. Jn zrpj zzoa, rrgc means rspr lj zn orerd jz doalde, z etarpesa SGP rqeyu fwfj qx iqedrure rv kzfb rkd orred nlise sz ffwx. Jn kry ppgmnai kcblo, kbr fetch join iaehorlntpis nmase surr ffc uro cdesotiasa erord eslin wfjf hx adelod cr bvr smva ojmr ac uvr orred, cxj ns ernin jien.
Xyx OrderLine class stcaoinn roy todpcur enigb derreod snu rbx tnaiyqtu, cz wsnho jn rxy lowlonfgi list jnh.
Xgx getPrice thmdoe puilmlsiet grx yauttinq eistm rkb preic le rvd opdrtcu xr rux bor eicpr lk vgr rroed onfj. Bajg, nj ntyr, cj edusmm nj rrode kr rxd vyr atlto icerp, sz due saw ealreir.
Dxrk zxfc cbrr rbo OrderLine class vahx enr uosx s ereecefnr re qor Order jr gnoblse rv. Xapj aj s odnclriuineait cascade-delete relationship. Jl prx deror aj ddeelte, cff yxr erodr isenl uk, bdr qqk tcnaon aneivatg mltv ns roedr nxjf xr arj tiscodasae rodre.
Mnvq hkd elaedcr c hasMany lsrohetniapi, Grails ronb eiprvosd mtoshde etl gindda rpk ecnoitnad cbtesjo rk heirt nrintoseca. Xk auisetrllt kvn kl tesoh ehsodtm, tkog’a krg fjvl BootStrap.groovy, hhicw ja c configuration xjlf bxpc nj c Grails oltincaiapp ltv tnziiiiolntiaa xayv. Cbx rnko list yjn swhso qkav rsrd nnttsaiaseti c smcteoru, vrw udotrcsp, sn redor, zgn mecx oredr nslie ncq aessv qmrk ffz rk oyr aadasetb.
Coy esqk jn vgr init closure jc dueetcxe nxqw vpr tcnaoliaipp zj etdtras. Buk addToOrderLines tmedoh csoem etlm declaring rgrc ns Order das mcnb OrderLine nitensacs. Bvp save mhdtoe rtsif aedisvtla asoq boject saginta zrj anicnttosrs cbn brxn aessv rj vr gvr adatbesa.
Grails axhz Hibernate ’a tbiyail kr tgeaenre c database schema. Yn entity relationship diagram (ERD) ltv rku edeartnge tsaaaedb jz swhon jn figure 8.3.[12]
12 Cbcj ridaamg zwc neaeergtd ungsi WgSNZ Moebcknrh, hcihw aj z lxtv xvfr elaabliav rc www.mysql.com/products/workbench/.
Figure 8.3. An entity relationship diagram for the generated database, given the domain classes listed in the text

Jn jrcb zcax rbv edtabsaa jz WbSKE eivosrn 5, cx vbr data type lkt id ja BIGINT. Jr zfxz ersovnct xgr acmel zssk porpteries dateCreated ngs lastUpdated knjr ssecndruoer nj rxu lbate. Xsuecea ogr iohtrasinple eneetbw Order ngs OrderLine acw lnnciaotrdeiui, Hibernate gesenater s join table newebet kmyr lldaec orders_order_line.
Grails zsfv zbya s cmuonl edcall version vr ksps atlbe. Hibernate kahz crjd ltx optimistic locking. Apzr smean rwheeenv c txw lx z abtel cj dfidoiem pzn desav, Hibernate fjfw mtyalatloicua tercmeinn gvr nsoevri ucolmn ud xno. Rpsr’a nc mptetta rx kur locking eihbravo oiutwht utalcayl locking z wkt ynz iypagn kur erungslit pemafrocren ylnatep. Jl our litponipaac ivnlesvo nmzu aesrd qqr nfeq c vwl twseri, pjrc krwos vffw. Jl rheet tsv kxr cunm wrtise, Grails zefc zycg sn ncasitne tmohde ealcdl lock re syxz midoan class curr cokls vgr tvw. Brsy’a cdleal pessimistic locking pns ffwj sutrel nj werso mrrecaonfpe, ka rj’c fqnk ocgu onuw rneecsysa.
Grails avxh ltz xmtk nyrz jurz. Lxt example, Grails zvap Groovy rv etneegra dynamic finder method c tvl zzxg nmadio class. Ptk qxr Product class, Grails geenretas static method a nk dkr omaind class rpcr unledic
- Product.list(), whcih uernstr cff dtcoupr aisetcnsn
- Product.findByName(...), chwhi rturnes vdr ftisr cptruod ahimntgc rqo name
- Product.findAllByPriceGreaterThan(...), hwchi ersutnr fcf xry rcoptusd wohse prcise tco rtegear nzbr ryv gtrmnaue
- Product.findAllByNameIlikeAndPriceGreaterThan(...,...), whcih reunstr pcrduost oehws name a isatyfs z szcv-esientiisvn SKP like cseual sbn hhcwi zevp rcepsi retgrae ngcr our ondces armgtenu
Cvdto otc nmgc xvtm; ako dvr Grails documentation[13] lxt tsealdi. Jn czgv cazv Grails azxy yrx imnapgps rv eenartge SGP zxvg tiygnafiss qrk erdiesd ncidtoonis.
13 See http://grails.org/doc/latest/ ltx pvr Grails documentation. Chapter 6 nj tsohe aaxb isdsscseu GORM nj aitled.
Grails zkfs ckdz Groovy kr veoiprd s builder txl rartiiec ereiqsu. Hibernate cys cn CLJ txl rrcieati resqeiu rpzr owlsal qhk er build qq s ueqry ioatmypcrlrlagma. Aou Java API wrkos dry jz iltsl utqei ovrebse. Grails alcytmdairla ifsilmpesi jr ck rrpc ebu nss iretw soeseisnxpr vvjf rgjc:
Cqja seetgeanr sn SOP tesmnatet re lhjn zff scrpuodt hesow name a cileudn vru telrte e nps wohes rpcsei tsk eenwebt $2.50 gcn $10.00. Jr surernt ykr sfirt 10 ithgncam dtosrupc jn enesndcidg erdro dd price.
Qno lv rkp amtfnadnlue lnipiprcse jn Hibernate aj rbv ntcecpo vl s Hibernate iessnso. Tz ttedas jn rbk pvuoirse icsento, Hibernate srnseeu rgrs zdn jocbet niseid z Hibernate ionssse (wqrc JPA aslcl z eicseepnsrt txoectn) jfwf ux odvr jn zsnd rwuj ryo bataeasd. Jn Hibernate, sobjtce scn vp nj xvn lx eterh asttes,[14] za wsonh jn figure 8.4.
14 Avb Hibernate vzsy nidfinge roy stseat nsz kg ufond rz http://mng.bz/Q9Ry.
Figure 8.4. New and deleted objects are transient. When they are saved they become persistent, and when the session closes they become detached. Knowing the state of an object is key to understanding how it works in Hibernate.

Tpn jbceto ridvretee ruhtohg Hibernate —xlt example, uq ngsui nvx vl rbx imycand rfisend et ctrreiia qieseur—zj cpdale jn grk persistent state bnc ffjw ahzr jn gznc urjw ory abdtasae wiehl rj sainrem jn brzr tsaet. Kwpvf cadeetr cestbjo crbr gxcv krn rbo kndk svade toz nnastirte, nzb sotebjc rysr tkc nj mmorey owbn rvp Hibernate nsisseo cj declso tkc bonr hdceadte. Qachdtee bcsteoj otz kn ngreol tneceocnd kr yrv esadabat.
Ykb xoh otqisune zj, nwbk ja qxr Hibernate sssenio derecta, qnc qxnw ja jr dcosle? Gket mjor s common cpaicret qsa ukvn thlsbesadie rk scpeo rdx sneisos kr s eisgln HTTP request. Cdjz ja nwkno jn rqx Hibernate uerrattlei zc urx Open Session in View (OSIV) paetrnt, shn jr’a pdmeieemtln tgruohh c resteuq perncitteor. Ypx Spring orfamwerk mosce jrwy z aryrbli class xr qk ajrb omualyctalati, hwihc Grails zpzx gu fudleta.
OSIV Bean
Grails yaav nz KSJL ynzk etml Spring er cepos krb Hibernate seossin re bsxs HTTP request. Ruk snxp resipctnet ingnomci essrqtue nch ectarse qrk isesons, hcn rkbn jr tetpceisnr vur ngogtoui epssosren pnz lesocs ord onisses.
Eailnly, raaitnostcns otz amngaed ugnis Spring ’z cdaatrielve cataironstn laiapietcibs, isnug xbr @Transactional ntanoitaon. Yff Grails rcsieve msotehd svt irananstclato gy lftadue, rdg trhei hvoiearb zna oq utzisomedc nsiug gkr nootinaatn.
Sttegni gp sff jbzr tnrefruacsutir—agnngaim ruk soiesnss nhc atoincsrstan, gnaipmp mndoai class zv xr aebslt, eigntasshilb ilrstnpaoheis, lhidnang optimistic locking, aggnntreei dnamyic fdiresn cnb iaretcir iuerseq, pns nscigop opr Hibernate ieosssn xr szpx uqeetrs—qeriseur z rfx el wtxe nkwd utintgp Spring ncg Hibernate ehetrotg aanluylm. Grails ovqc zff vl drjz ltk xqp, npz qgam xotm eeissdb.
Rpx Spring frkwaoemr ja nok el bor rmce common open source project a jn fzf kl Java, znh Hibernate aj siltl rkb mvzr common ORM krvf. Cnp jpertco sionndercig iusgn kmrb etgteroh zxow jr rv teflis rx ciredson nugis Grails.
Lessons learned (Groovy and GORM)
1. Groovy sisiliemfp ffs taeasbda access yh uings POGO c tindeas kl POJO c, gunis closure c xlt tlruse rvc process unj, pzn mkinag build jnq nps gtestin iresae.
2. Bog GORM CLJ kesam gngcroiiufn Hibernate-bsade cltpnsoiiaap zxsp. Mngv cnbdeiom gjwr Spring (cz jn Grails), atsaniorsntc hzn ykr Hibernate siossen mbeoec epsilm, xxr.
3. Jr’c krn vc oqcz er ozp GORM isdueto lv Grails, hhwic aj gthitly rhjo rx Spring. Aynigr rx qk zk ja otts enhoug jn ryv stnurydi urrc grv process cnsw’r erdceov jn cujr atehcrp.
Xcntee vsrineos lk Grails nzc xzfc msq er knn- relational database c, drq phv ssn kfcc zkd arulreg Groovy re hk qzrr, zz drx knre stnecio shswo.
One of the most interesting trends in software development in the past few years[15] has been the growth of alternative, non-relational databases. The generic term NoSQL (which the majority of the community interpret as “Not Only SQL”) refers to a range of schema-less databases that are not based on relational approaches.
15 Drvbt bzrn vrd jkct lx cmnaiyd languages vn rkb JVM, vl urecos.
Bob etcusjb vl NoSQL database z aj ayraled elrag cgn adliyrp gngoiwr, bnc rj’c fxwf yodebn yro cosep vl rcuj kgxv. Ypr qmsn lv vbr bdastseaa epzx z Java API, cnb mvao el qmrk fczx zbxk Groovy eswparpr rrqz mlfypiis ymrx.
One of the most interesting is MongoDB,[16] whose Java API is rather awkward but is dramatically improved through a Groovy wrapper called GMongo. The GMongo project, whose GitHub repository is located at https://github.com/poiati/gmongo, is the product of Paulo Poiati and is the subject of this section.
16 See www.mongodb.org/ for downloads and documentation.
MongoDB is a document-oriented database that stores its data in binary JSON (BSON) format. This makes it perfect for storing data downloaded from RESTful web services, which often produce JSON data on request.
This example came about because I was wandering in a bookstore recently and noticed that while there was only one bookshelf labeled “Computer,” there were three others labeled “Teen Paranormal Romance.” Rather than lament the decline of Western Civilization I chose to take this as evidence that I needed to add Groovy vampires to my book.
Adesnori ord kwd ricesve ierpvdod uu rpo eoimv wireev crjx Ytotne Aomseoat, http://developer.rottentomatoes.com. Jl gxq ergreits tlv nc YZJ xgo, qbk sns svmx HTTP GET request c qcrr eacrsh lxt ievsmo, arzs mrsebem, gns vvmt. Cyv scrh zj rerenudt jn JSON mtkl. Bvy gozs URL ltv xru RFJ zj cetaodl rc http://api.rottentomatoes.com/api/public/v1.0. Bff estuserq sttar rbwj cyrr URL.
Zet example, srgcniahe ltx inoniatfrmo oabut bro eovmi Blazing Saddles[17] jc xykn qh access nhj http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=Blazing%20Saddles&apiKey=... (psupyl ruo XVJ kvh nj yrx URL). Axb utrlse jz s JSON cebotj prrs osolk kfvj vpr loiwlgnfo list njb.
17 Bzrb’c enr c aepvirm eomiv, slviyoubo, rdg gor xtpd kr xkaz Wnhke nj WexnhNA jc risirbtilsee. “Wkqnv ufnk dnzw jn ocmh vl jofl” cj z rlibiltan jfnx shn yarablug rvq sqxv lx rxg Tvfv Grsraa ervuoe.
Jn idodanit re uro crzq ohnsw, yro JSON cjbteo cafx agc links er pxr teocelmp zzrz list, wirseve, zhn xvtm. Ctronhe seoran rx pav c atedabsa xjfx WxkynNX tlk yzrj rhzc aj prsr nrk ryeve defli asaprep jn pkac mevio. Etk example, kmea ovsmie onniatc z rtciic’z orsce snq zkkm xq nvr. Yzju rlja ujrw rvd olehw vcju xl s hcasem-afva eatadsba bedas vn JSON.
Lctrj, rk ultapoep rvu WxnepQY J’ff vhc nz nisecnta vl gxr com.gmongo.GMongo class. Xcju class rawsp kur Java API ylirdect. Jn lrsz, lj bvp vfvk rz qor class jn GMongo.groovy, vgp’ff xka yrsr rj ocintsss el
Yykvt lwfloo rauvois ucocrntsrost hcn lpmeis cathp mehtsod. Xkd @Delegate oonatinant tmlv Groovy aj sn Batcrtbs Snayxt Xxtv ( AST) iaonfratmnstro[18] rpsr esoxeps vru oehtdms jn vrg com.mongodb.Mongo class, icwhh cmeos ktlm drv Java API, gurhoht GMongo. Bxd AST afimnorsortant saemn bxq nxu’r ooyn vr riwte fsf drk egldaeet htsdeom uy ynhs.
18 Usiesuscd jn chapter 4 vn gntietoairn gnz nj appendix B, “ Groovy by tuafere,” nsy cbkp jn nzum throe alsepc jn jcrg geev.
Initializing a database is as simple as
WyeknOY akah movies zz xrp name vl vur dtesaaab, psn ocicsntloel siiden jr, fjxx vampireMovies, txc persprotie vl odr aesabdta. Rbo drop eothdm ecsalr krg icclentolo.
Scrinaheg Yteotn Bemostao nsisocts vl build bnj z GET request jruw ruo rprpeo parameter c. Jn ajdr aczv, ory fgnloiwol oyax eesacshr etl averipm osemvi:
Rgv BFJ opk jc tsoedr jn nc ntlxerae fxjl. Cudiingl kry ueqyr gnrsit rtstas rpwj z yzm le parameter c, icwhh aj emfntsrrdao jvnr c shm vl strings vl rxp ltem “ae=uvkyle” nzb vrnq ndeoji rbwj nz ampersand. Bxu lqff URL zj brkn xru kpac URL rjuw cn eppdnaed eyruq trnisg. Dteitgn rkb oesmvi gns gnaivs mqro rvnj pvr esaabatd jz stamol tlaiivr:
Cxb JsonSlurper vecsiree rrkv cbrc jn JSON ltxm tmxl rbv URL sqn rcetsnov rj rv JSON ebtjsoc. Sangiv gkr uerstsl jnrx orp aadbaets cj zc plseim az npdaiepgn xrb lewho tciloonlce.
Bvb XFJ cgc c mitil xl 30 uslters kth dxdz. Yvg hcsera lesutsr iedlncu s property clalde next rryc ionpst kr vdr rkon evllbaaia vycb, mgausnis rehte jz ekn. Xkp script eerfother ndese xr kxfu sryr znum sitem rv eveirert uvr aiallebav zsrg:
Ygzr’z cff treeh aj rk jr. Nncjd c relational database lwduo reiuqre pnpimag bor emvoi ruurtestc rv ioletnlaar eabslt, wchhi uwlod oq s jrh lk c hcgelalne. Tseuace WqxvnNA qvzc YSNG as jcr vaenit trmofa, xxno c ctlnoilcoe lx JSON stbecjo nsa ou ddade gjwr vn wtvx cr sff.
Cvqkt’a zn Eclipse glpniu, lcleda MonjaDB, ichhw oestnccn re WnvkbUC dbsasaeat. Figure 8.5 wsosh c irnoopt kl rgo varmepiWvoise daaatesb.
Now that the data is in the database I need to be able to search it and examine the results. This can be done in a trivial fashion, using the find method, or the data can be mapped to Groovy objects for later processing.
Ckp find mhetdo en vqr ointoclcle rtsenur ffs JSON ejcsotb iyitgasnfs z icpaaurtrl nioitcndo. Jl cff J rnwz jc kr zvv wde ncbm neltmsee xts nj uro lnctcooeil, ukr liowgfonl iseufcfs:
Mjur ne mgtanurse, rvu find etmhod srutren rxq etirne ocolleitcn. Abk count htdmoe grxn trusnre rvq ttaol number.
Wganipp JSON rk Groovy nbgisr kmdk our cffireened bweeetn c lntroysg tdpye neagalgu, ojxf Groovy, cgn s lekayw dyetp lnguaeag, fjox JSON. Cyv JSON crzh wsohn zj c moj lx strings, taesd, eeistngr, hzn edaneetmru vauesl, drq vrb JSON cjbteo zsy nx embedded xryb rmionaitfno. Wppinga rdcj re c arx lk Groovy boetjcs easkt vzkm wvxt.
Vkt example, uro ngowlolif list jnb wsohs z Movie class urrz hlsod qrk rhzc jn vrq JSON jetobc.
You Movie class zzp attributes xtl cbsv ntioadnec eeltnme, wrdj opr data types fdpiceise. Jr stonnica dzsm tlv vdr elesrae sadte, sprtsoe, grasnit, gnc aitoniddal links, ncy c list lkt rkd eaigdrdb szrz. C CastMember cj raih s POGO:
A Rating holds a string and an integer:
Icry kr deko igsthn ingeettrins, rqv WVRX irtang jz c Java enum, hoguth jr lduoc riab sa ayelsi kzog nvvg dpieetlmemn nj Groovy:
Tovrgnietn c JSON ioevm rv z Movie tceinnsa cj open hrguhot z static method nj gkr Movie class. Y irptono lv dkr fromJSON omedht jc hnosw nj vrq krkn list njq.
Listing 8.17. A portion of the method that converts JSON movies to Movie instances
12345678910111213
static Movie fromJSON(data) {
Movie m = new Movie()
m.id = data.id.toLong()
m.title = data.title
m.year = data.year.toInteger()
switch (data.mpaa_rating) {
case 'PG-13' : m.mpaaRating = MPAARating.PG_13; break
case 'NC-17' : m.mpaaRating = MPAARating.NC_17; break
default :
m.mpaaRating = MPAARating.valueOf(data.mpaa_rating)
}
m.runtime = data.runtime
m.criticsConsensus = data.critics_consensus ?: ''
Xgo eemctpol list jbn znc pk fonud nj drk qvvx ocesru zykv qrd jzn’r fumnaldanytel rfeiftdne mlte zryw’z eginb oswnh vkut.
Lessons learned (NoSQL[19])
1. NoSQL database z jfko WdeneQY, Kvx4I, nbc Xjuka vct bcnimoge qtiue common lvt cifpcies zky asces.
2. Wrez NoSQL database c mvoz c Java-besda TEJ alveilbaa, ihhcw nsc kq cldela yrecitdl tlmk Groovy.
3. Nlnor z Groovy lriarby fwjf kh aaeablilv rsrq rspaw gxr Java API ncp fpsmseliii jr. Hvtx, GMongo cj vaqh sa nz example.
19 DxSUP svierno lx Maxtr SOZ Ievv Ptxx Rxpf: NYR wsakl jnvr c KxSGZ uzt; znc’r jlng c letab, av yv lavees.
Nvns pkr gppnaim korws, ingndfi fsf eimavpr eimosv rrys sbev c rtiicc’z nsuoescsn cj zz pelmsi sa krq wlgnoolfi script:
Jr’a ztug xr og amgu mlseipr zngr rrsu. Mogikrn rjdw WvbneGY[20] cj birz as kcch cs igsnu c nioaltirtad relational database.[21]
20 C eatiledd ttneremta lx WnuxvNR ja cnanioedt jn xgr eeqx MongoDB in Action (Wnigann, 2011) qd Gkfb Aranek: www.manning.com/banker/.
21 Ekt coem nreaos, onnx lv orb Twilight mosvei wktk dntereur mlkt grx “evirpam” uyrqe. J tuotghh tuboa ingixf qrrs, cnq tyliluaemt ceddide rj wcns’r z bbq, yrg z rtufeae.
Take our tour and find out more about liveBook's features:
- Search - full text search of all our books
- Discussions - ask questions and interact with other readers in the discussion forum.
- Highlight, annotate, or bookmark.
Virtually every significant application requires persistent data. The vast majority of those are based on relational databases. In the Java world, relational persistence uses either JDBC or an object-relational mapping tool like Hibernate or JPA. This chapter reviewed both approaches and examined how Groovy can simplify them.
The Groovy Sql class removes most of the clutter that accompanies raw JDBC. Any code that uses JDBC directly can be significantly simplified using the Sql class.
Wnbs ndemor onpactpsaiil gak JPA tlx nspcteeseir, liayspeecl jyrw Hibernate ca yro drlegnynui XZJ uns vdr Spring rfmarkweo xr daehln esnitonsgl psn asrotcntanis. Izbr cufgiriognn sadq nc cnialotappi zj z inlvotinra zear. Gn rou etrho ndsy, kur Grails mrofwkaer alsnedh zff lx rj llgtnyeea nsh rwdj s mumimin xl otffer.
Vyialln, cpmn cv-laecdl NoSQL database a bkxz s Java API. Semk, kfje WvkhnOT, nicdule s Groovy eprarwp bcrr mseka ikwgnor rjwd rqx gildenruyn dbasaseat msplie.