The Revolutionary/Evolutionary Database Projects (and Dev11)

   Posted by: Dave Zimmerman

I have been working with database projects since the 2006 CTP “Data Dude” days through its 1.0 release as Visual Studio Team Edition for Database Professionals; Its realized vision -- of organizing our database artifacts/schema into a solution; checking changes into source control (TFS) surrounded with descriptive meta data (work items) documenting the motivations for those changes; and empowering us to automate the build, deployment, and test of those changes through our staged environments – has truly been revolutionary for this aspect of software development for those who have persevered in the new discipline.  Those of you who have been using this for a while also know that tools and best practices surrounding database projects has been very evolutionary as well with each release of Visual Studio, not to mention each release of SQL Server.  The Dev 11/SQL 2012 release is no exception here.

The latest release of Visual Studio (Dev 11 at the time of this post) will upgrade your databases project (.dbproj) to a database project (.ssdt) which stands for SQL Server Developer Tools.  This is a major rework by the tools team which is now fully aligned with the various SQL server cleints with the aim of providing a unified toolset for all SQL Server Development whether you are working in SQL Server Management Studio (SSMS), Business Intelligence Design Studio (BIDS), or Visual Studio (VS).  We have been reading about this effort and/or playing with these features in Community Technology Previews (CTPs) which began integrating with Visual Studio 2010 Premium SP1 in CTP3.  The Visual Studio Dev11 Beta shipped with the release candidate 0 (RC0) of the SSDT tools.  The SSDT tools have since been released to manufacturing (RTM).  Thus, if you want to play with these tools in Dev11, a good place to start is to either download and install the Feature Pack for 2012, or just install the required VS components for the VS dev-build-deploy cycle.  Specifically for me, this consists of 64-bit DACFramework.msi, SqlSystemClrTypes.msi, SQLDOM.msi, and SQLLS.msi.  Those of you installing on 32-bit build machines, would want to install the 32-bit versions of those downloads.

Dev11 Bug Alert: If you are getting the following error on your Dev11 64-bit build machines when you go to build your .ssdt projects:

clip_image002[6]C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets (381): The "SqlModelResolutionTask" task could not be loaded from the assembly C:\Program Files\Microsoft SQL Server\110\DAC\Bin\Microsoft.Data.Tools.Schema.Tasks.Sql.11.dll. Could not load file or assembly 'file:///C:\Program Files\Microsoft SQL Server\110\DAC\Bin\Microsoft.Data.Tools.Schema.Tasks.Sql.11.dll' or one of its dependencies. The system cannot find the file specified. Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.

Workaround: This is due to a bug in the Dev11 build targets.  The workaround is to copy your DAC files from the (x86) Program files directory to a 64-bit location, for example:

C:\Program Files (x86)\Microsoft SQL Server\110\DAC\Bin\

gets copied to

C:\Program Files\Microsoft SQL Server\110\DAC\Bin\

Not So Fast On that Uninstall

Great strides have been made with SSDT projects.  Just to name a few, developers working offline in declarative mode using LocalDB or online interacting with a shared database both get a greatly improved Transact-SQL Debugging and testing experience; one database project is used for all versions of SQL Server and the organization of database artifacts is much friendlier/more intuitive than the previous .dbproj.  On the other hand, while there are many great new features, not all the old features of database projects you may be taking advantage of have made it into the SSDT code rewrite (See SQL Server Data Tools CTP4 vs. VS2010 Database Projects ) and conversions aren’t no-brainers for all database projects (See Top VSDB->SSDT Project Conversion Issues)  [As an aside, our upgrade team was not impressed with the upgrade logic used by the database project conversion wizard.  If you don’t mind not losing your seamless history of artifact changes in your .dbproj, I recommend just pointing at a database and recreating your solution as an SSDT rather than the really odd arrangement of new and old scripts you acquire over time while working with a converted .dbproj file.  However, for those who do want to keep this history, manually upgraded, e.g moving artifacts to the appropriate folders and deleting others is a tedious option.] 

SNAGHTML155916c

Example of “upgraded” database project which preserves the .dbproj artifact organization.  Unfortunately when new artifacts get added, the solution places them in the new .ssdt folder organization.  (Now we have 2 “Production folders” – and a solution which is in neither the .dbproj nor .ssdt canonical form,  Worse yet, you may start getting compiler errors after synching table changes because with .ssdt projects index scripts are stored in the table definition itself for readability (Nice!), But it does not clean up the .dbproj’s pattern of storing index scripts as separate files.   

So in your exuberance over the new features, don’t be too hasty clicking Uninstall on your dev machine and build machine VS2010 installations, especially if you want to continue using features, like for example, the data generation/compare tools.  But keep a stiff upper lip as well, Microsoft is already narrowing the gap with out-of-band power tools that integrate with the 2012 tools (See  SSDT PowerTools which at the time of this writing has re-integrated the Schema Explorer with .ssdt projects) 

Hibernate Lazily Loaded One-To-One Associations

   Posted by: Jim White

A couple of weeks ago, in my Complete Hibernate class, a student of mine was conducting some of his own experiments with lazy loading at the end of a lab. My class had just learned of Hibernate?s lazy vs. eager loading and the consequences of dangling proxy objects after a session had closed.  He discovered feature in Hibernate that even surprised me.

Hibernate Lazy Loads by Default

By default, Hibernate lazy loads (see here for details), which means when a persistent object is loaded into memory (say with a query or call to get or load) the associated objects are not created. Instead, Hibernate builds a proxy object as a stand-in to represent any associated object. During a session, if an associate object is accessed, Hibernate replaces the proxy with the real object. However, if the session has closed and code tries to access the proxy object (as the real object), an org.hibernate.LazyInitializationException is thrown.

One-to-one Loads Eagerly by Default

My Hibernate student had created a one-to-one relationship between objects and was testing out this default behavior. Surprising (to both of us), when he tried to reach the associated object on a one-to-one mapping (configured with default settings) after closing the session, the object was not a proxy and no exception was thrown!

To better facilitate the understanding of this situation, assume you have two persistent classes: Foo and Bar. Here is the code for both Foo and Bar.

   1: @Entity
   2: public class Foo {
   3:  
   4:     @Id
   5:     @GeneratedValue(strategy = GenerationType.AUTO)
   6:     private Long id;
   7:     @Column(name = "FOO_NAME")
   8:     private String name;
   9:     @Column(name = "FOO_DATA")
  10:     private int data;
  11:  
  12:     @OneToOne(cascade = CascadeType.ALL)
  13:     @JoinColumn(name = "bar_id")
  14:     private Bar bar;
  15:  
  16:     //  ... getters/setters/constructors not shown
  17: }
   1: @Entity
   2: public class Bar {
   3:  
   4:     @Id
   5:     @GeneratedValue(strategy = GenerationType.AUTO)
   6:     private Long id;
   7:     @Column(name = "BAR_INFO")
   8:     private String info;
   9:  
  10:     //  ... getters and setters and constructors not shown
  11: }

Note, via JPA annotations, Foo is associated to Bar in a one-to-one association. However, also note that except for the Cascading Style, no other defaults are overridden in the one-to-one association. So, by default we all assumed Bar to be loaded lazily, which again is the standard Hibernate behavior.

Surprise! When Tom ran his code, using the test case below, the associated Bar instance was getting created and associated to the Foo instance when the Foo instance was obtained. That is, the example code below worked without issue (in particular, note the last two lines of the main method).

   1: public class TestLazy {
   2:  
   3:     public static void main(String[] args) {
   4:  
   5:         Foo foo = new Foo("myfoo", 1234);
   6:         Bar bar = new Bar("some info");
   7:         foo.setBar(bar);
   8:  
   9:         SessionFactory sf = new AnnotationConfiguration().configure()
  10:                 .buildSessionFactory();
  11:         Session session = sf.openSession();
  12:         Transaction trx = session.beginTransaction();
  13:         session.saveOrUpdate(foo);
  14:         trx.commit();
  15:         session.close();
  16:  
  17:         Session session2 = sf.openSession();
  18:         Transaction tx2 = session2.beginTransaction();
  19:         Foo f2 = (Foo) session2.get(Foo.class, 1L);
  20:         // at this point bar on foo instance should be a proxy.
  21:         tx2.commit();
  22:         session2.close();
  23:  
  24:         // if bar property on foo is a proxy, this should cause a
  25:         // LazyInitialization exception.
  26:         Bar b2 = f2.getBar();
  27:         System.out.println(b2);
  28:  
  29:     }
  30: }

Why? Some digging in the Hibernate documentation uncovered a small oddity. It turns out that when in a one-to-one relationship (and when the associated object is optional), it is actually more efficient for Hibernate to just load the associated ?one-to? object as opposed to build a proxy. See here for more details.

How to Get an Associated ?One-to? Proxy

In cases where you actually want a proxy (remember, it might actually be more efficient to just allow the one-to-one associated object to be loaded ? even when not used), make explicit the lazy loading on the one-to-one annotation so that Hibernate builds the proxy as you (and your code) might expect.  Below, the Foo class has been ?fixed? to get Bar to load lazily fashion.

   1: @Entity
   2: public class Foo {
   3:  
   4:     @Id
   5:     @GeneratedValue(strategy = GenerationType.AUTO)
   6:     private Long id;
   7:     @Column(name = "FOO_NAME")
   8:     private String name;
   9:     @Column(name = "FOO_DATA")
  10:     private int data;
  11:  
  12:     //  Add the explicit FetchType
  13:     @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
  14:     @JoinColumn(name = "bar_id")
  15:     private Bar bar;
  16:  
  17:     //  ... rest of the code removed
  18: }

Of course, when you run the test code shown above again with this new setting, you?ll get the expected LazyInitializationException.

image

Wrap up

Are you struggling with Hibernate (check out our Complete Hibernate class offering) or other Java open source framework?  Need some help with learning Java technologies or implementing Java EE applications?  Call or email Intertech.  Let our staff of Java experts help you get up to speed faster.

Processing XML Files with Groovy: Creating

   Posted by: Jeff Jensen

Intro

Do you write code that reads and/or writes XML files or in-memory structures?  XML files are a useful data exchange for programs, but are not usually fun to hand-edit code for in most languages.

If you haven't seen how easily Groovy handles XML data, read on...  It can simplify the coding such that you will probably want to use Groovy for this next time!  It can be particularly useful with test data.

This post covers an intro how to on creating XML with Groovy.  I plan to cover an intro how to on parsing XML with Groovy in the future.

For the examples, while much Groovy convention is to chain method calls, I deliberately separated object definitions and method calls into more simple statements to help understand the separate pieces as an introduction.  Additionally, the examples were written with Groovy 1.8.0.

Creating XML

Groovy primarily has the MarkupBuilder and StreamingMarkupBuilder classes that do the XML creation dirty work (along with their helper classes).  These examples only focus on the StreamingMarkupBuilder as it also has namespace support and handles large documents with less memory usage.  However, using the others is very similar.

The "writeFile" Method for All Examples

Before jumping into the XML creation examples, we need to cover a common method used by each example: "writeFile".  I extracted the common code from each example to it to simplify the example, and show the near-template code for setup and use.

   1: def writeFile(fileName, closure) {
   2:     def xmlFile = new File(fileName)
   3:     def writer = xmlFile.newWriter()
   4:  
   5:     def builder = new StreamingMarkupBuilder()
   6:     def Writable writable = builder.bind closure
   7:     writable.writeTo(writer)
   8: }

The writeFile method requires two parameters (line 1):

  • The first parameter is the full path of the file name to create.
  • The second parameter is the closure passed to the StreamingMarkupBuilder's bind method.

Using the StreamingMarkupBuilder class:

  • The bind method requires a closure and returns a Writable instance (line 6).  The closure contains the code for generating the XML.  The bind method will invoke the closure to generate the XML.
  • Use the Writable (line 7) to output the XML from the closure to the desired destination, whether a file or a String (review the doc or use autocomplete in your favorite IDE to learn the other uses of Writable).

The following examples will explain creating the closure for writing. the XML.  They start with a simple example and each adds one new "feature" to help keep this "how to" clearer.  The last example shows dynamically generating the XML from a map of data versus statically defined in the closure.

Example 1: Simple

Example 1 shows creating a simple XML file from static elements defined in the closure.

   1: def createFromStatic_Simple() {
   2:     def xmlClosure = {
   3:         docroot {
   4:             element(1)
   5:             element('b')
   6:             element('c' + 'c')
   7:             element(2 + 2)
   8:         }
   9:     }
  10:  
  11:     writeFile('/createFromStaticSimple.xml', xmlClosure)
  12: }

 

Example 1 creates the following XMLfile (note: it's created all on one line without formatting; it is formatted it here for readability):

   1: <docroot>
   2:   <element>1</element>
   3:   <element>b</element>
   4:   <element>cc</element>
   5:   <element>4</element>
   6: </docroot>

Comparing the closure defined starting on line 2 of the code example with the created XML file, notice the direct use of the closure structure names and evaluated expressions in the XML file.

  1. Literal names in the closure structure become the element names in the XML file.
    • "docroot" and "element" become element names.
  2. Expressions inside the parenthesis are evaluated and used as the element's value.
    • 'c' + 'c' on code line 6 becomes "cc" on XML line 4.
    • "2 + 2" on code line 7 becomes 4 on XML line 5.
  3. Elements inside the curly braces become the next nested level inside the named element (they are each closures - anonymous closures as they are not bound to variables - and are evaluated at runtime).  The "element"s on code lines 4-6 become <element> entries on XML lines 2-5.

Note: It's important to place the subsequent element definitions on their own line, otherwise, Groovy will dynamically interpret it differently, usually as a map!

Example 2: Nested Elements

Example 2 also shows creating an XML file from static elements defined in the closure, and adds a second nested level of closure elements named "inner".

   1: def createFromStatic_Nested() {
   2:     def xmlClosure = {
   3:         docroot {
   4:             element {
   5:                 inner(1)
   6:             }
   7:             element {
   8:                 inner('b')
   9:             }
  10:             element {
  11:                 inner('c' + 'c')
  12:             }
  13:             element {
  14:                 inner(2 + 2)
  15:             }
  16:         }
  17:     }
  18:  
  19:     writeFile('/createFromStaticNested.xml', xmlClosure)
  20: }
 

Example 2 creates the following XMLfile (note: it's created all on one line without formatting; it is formatted it here for readability):

   1: <docroot>
   2:   <element>
   3:     <inner>1</inner>
   4:   </element>
   5:   <element>
   6:     <inner>b</inner>
   7:   </element>
   8:   <element>
   9:     <inner>cc</inner>
  10:   </element>
  11:   <element>
  12:     <inner>4</inner>
  13:   </element>
  14: </docroot>

Once again, notice the direct use of the element names in the XML file, this time with the addition of another nested element level named "inner".  The same value expressions are moved from the "element" element to the new "inner" element, still within parenthesis.

As the code example shows, to add a nested element, just create a nested closure.

Example 3: Attributes

Example 3 also shows creating an XML file from static elements defined in the closure with nested elements, and adds attributes.

   1: def createFromStatic_NestedAndAttributes() {
   2:     def xmlClosure = {
   3:         docroot {
   4:             element(attr1:1, attr2:2) {
   5:                 inner(attr3:1, 1)
   6:             }
   7:             element(attr1:4, attr2:5) {
   8:                 inner(attr3:'b', 'b')
   9:             }
  10:             element(attr1:7, attr2:8) {
  11:                 inner(attr3:'c' + 'c', 'c' + 'c')
  12:             }
  13:             element(attr1:10, attr2:11) {
  14:                 inner(attr3:2 + 2, 2 + 2)
  15:             }
  16:         }
  17:     }
  18:  
  19:     writeFile('/createFromStaticNestedAndAttr.xml', xmlClosure)
  20: }

Example 3 creates the following XMLfile (note: it's created all on one line without formatting; it is formatted it here for readability):

   1: <docroot>
   2:   <element attr1='1' attr2='2'>
   3:     <inner attr3='1'>1</inner>
   4:   </element>
   5:   <element attr1='4' attr2='5'>
   6:     <inner attr3='b'>b</inner>
   7:   </element>
   8:   <element attr1='7' attr2='8'>
   9:     <inner attr3='cc'>cc</inner>
  10:   </element>
  11:   <element attr1='10' attr2='11'>
  12:     <inner attr3='4'>4</inner>
  13:   </element>
  14: </docroot>

The only difference between examples 2 and 3 is 3 adds element attributes.  To add attributes to an element:

  1. Specify the attributes inside parenthesis, comma separated, followed by an optional value expression as seen in examples 1 and 2.
  2. Specify an attribute with its name, a colon, and its value-expression.

Example 4: Dynamic Creation

Example 4 shows creating an XML file from a map of data using for-each loops in the closure.

   1: def createFromDynamic() {
   2:     def mfgs = [
   3:             'Boeing':['747', '737', '727'],
   4:             'Airbus':['A330', 'A350', 'A380'],
   5:             'Lockheed':['L100', 'L1011', 'C130'],
   6:             'Ilyushin':['IL-62', 'IL-76', 'IL-86'],
   7:             'Fokker':['F28', '50/60', '70/100']]
   8:  
   9:     def closure = {
  10:         manufacturers {
  11:             mfgs.each { key, value ->
  12:                 manufacturer(name:key) { value.each { model (it) }}
  13:             }
  14:         }
  15:     }
  16:  
  17:     writeFile('/createFromDynamic.xml', closure)
  18: }

Example 4 creates the following XMLfile (note: it's created all on one line without formatting; it is formatted it here for readability):

   1: <manufacturers>
   2:   <manufacturer name='Boeing'>
   3:     <model>747</model>
   4:     <model>737</model>
   5:     <model>727</model>
   6:   </manufacturer>
   7:   <manufacturer name='Airbus'>
   8:     <model>A330</model>
   9:     <model>A350</model>
  10:     <model>A380</model>
  11:   </manufacturer>
  12:   <manufacturer name='Lockheed'>
  13:     <model>L100</model>
  14:     <model>L1011</model>
  15:     <model>C130</model>
  16:   </manufacturer>
  17:   <manufacturer name='Ilyushin'>
  18:     <model>IL-62</model>
  19:     <model>IL-76</model>
  20:     <model>IL-86</model>
  21:   </manufacturer>
  22:   <manufacturer name='Fokker'>
  23:     <model>F28</model>
  24:     <model>50/60</model>
  25:     <model>70/100</model>
  26:   </manufacturer>
  27: </manufacturers>

The XML file structure is still defined in the closure (the element and attribute names, and their relationships), but the data is now pulled from a map.  This example shows a typical use - the map (or a list) could have been retrieved from a database or other source.

Conclusion

The examples begin to show easy ways to programmatically create XML files with Groovy.  While these simple examples should get you started, the potential processing is only limited by the closure logic.  Additionally, StreamingMarkupBuilder (and other builders) has some advanced features often accessed through "mkp", which is a special namespace used to access helper markup methods.

Resources

Groovy Metaprogramming

   Posted by: Intertech

There are always limitations to the programming language that we use. This becomes problematic when we need to do something that our language of choice doesn’t support, especially with a static programming language like Java. We often end up extending a class through inheritance to provide this new capability or we create utility classes to meet these needs. Either one of these approaches can become cumbersome and difficult to maintain.

Enter Groovy and its metaprogramming capabilities. Metaprogramming is the ability to add new methods to classes at run-time. This capability is considered by many to be one of the most useful features of the Groovy language.

Let’s say that you need a way to insert a space between each character in a string value.  This can be done using a Groovy closure.

Using a simple closure:
You could create a simple closure as a free-standing method:
def widen = {src->
  def newStr = ""
  for( c in src ){ // loop over the chars in a string
    newStr += c + " "
  }
  return newStr
}

Below is how you could use this closure:
println widen(“My Page Title”)

Producing the result:
M y  P a g e  T i t l e

Using Closures and the ExpandoMetaClass:
Every class that is accessed by Groovy code, either a Java class or a Groovy class, is surrounded by an ExpandoMetaClass (EMC) that intercepts method calls to it. So, even though the String class is final, methods can be added to its EMC. Groovy had to introduce a new concept called delegates to make all of this work. The delegate is the class that the EMC surrounds. The keyword delegate, is similar to the java keyword this. Because of the EMC in Groovy and the new delegate concept, we are able to implement the closure method widen() on top of the Java class String.

Or, you could create a closure to add the method to the String class:
String.metaClass.widen = {->
  def newStr = ""
  for( c in delegate ){ // loop over the chars in a string
    newStr += c + " "
  }
  return newStr
}

This implementation can be tested similar code to the simple closure example. This difference is that we are invoking a String method rather than a free-standing closure.
println "My Title Page".widen()


Overriding Method Behavior:
Another feature of closures and the EMC is the ability to override method behavior, without sub-classing the class in question. This allows you to alter behavior of an existing class method without changing the classes that use the method in question.

Using the example below, we can alter the behavior of the String.toUpperCase():
String.metaClass.toUpperCase = {->
  return delegate.toUpperCase(Locale.ENGLISH);
}

Using this closure, you could enforce the behavior throughout your application, that all String.toUpperCase() method invocations will return the affected String value using the English Locale rules.

Intro to Azure Data Synch Recording

   Posted by: Intertech

A big thanks to Liam Cavanagh from the SQL Azure team for presenting to our user group yesterday.  To view the recording click here.  To find out more about the Windows Azure User Group, click here.  We encourage you to register for the group (free) and you will be notified of upcoming events.  We also raffle off $1,000's of products from our sponsors.  Hope to see you at an upcoming meeting.

Hibernate's Primitive-Array

   Posted by: Jim White

By Jim White (Director of Training and Instructor)

I spent last week teaching several students from the Twin Cities (and a few virtual students from across America) Hibernate.  This group was fairly advanced in both their Java skills and even some Hibernate skills, so it was fun to watch them try to grab and dig into each and every feature Hibernate had to offer.

Hibernate Collection Mapping.

In the area of collection mapping, Hibernate offers may options for collecting ?the many.?  You can use a <list>, <map>, <bag>, <array> or <primitive-array> to map a collection (see here).  You can find some great examples in the Hibernate documentation and on the Web of most of these.  However, it was the last one, <primitive-array> that caught the eye of one of my students ? Jason.  Unfortunately, while I was able to explain its purpose, I could not find a very good example on line.  So, this week?s blog is an attempt to provide Jason, and maybe you too, with a more appropriate example and fill-in a gap you may also have found in Hibernate documentation.

What is a <primitive-array>?

First off, what exactly is a primitive array?  If you have a class with an array of primitives, you can use <primitive-array> to map the array property into an associated table.  For example, let?s say you had a BallPlayer class (representing a baseball player).  In the BallPlayer class, you might have standard simple properties for the player?s name, nickname, date of birth, etc.  If you follow sports, you know that players have a uniform number.  Furthermore, since players change teams, players sometimes change uniform numbers.  So, in order to know a player?s uniform numbers (past and present) you add a uniformNumbers property to your BallPlayer class.  You define the uniformNumbers property as an int array (int[]) as shown below.

public class BallPlayer {
private long id;
private String name;
private String nickname;
private Calendar dob;
private String birthCity;
private int[] uniformNumbers;
// getters, setters, constructors, etc. left off for brevety.
}

image

A <primitive-array> element in your mapping allows you to map an array of primitives to an associated table in the database.  Ball Player instances are stored in one table, while the associated array of primitives ? in this case ints ? is stored in another table.  Each primitive in the array gets its own row in the associated table.  Each row is identified by the primitive value and the id of the owning entity ? in this case the BallPlayer?s id.  However, when a BallPlayer is recreated from the database, the entire collection of rows from Uniform that are associated to the BallPlayer (by ID) are used to recreate the array of ints for the uniformNumber property.

image

Mapping Options

How do you persist uniformNumbers into the database?  You could, I suppose, convert the array of uniform numbers into a String.  Of course, you would have to read and parse a String in order to recreate the array of uniform numbers when you rebuild the object.  You could also use a collection (like a list) of wrapper Integer objects instead.  Then you could map the collection as a collection of value types ? also known as a collection of basic types (see here).  However, each of these solutions require you to change your class design to meet a persistent mapping need.

Using <primitive-array>

Using the <primitive-array> mapping element, you can directly map the array of instances to its associated table without conversion or wrapping.  Below is the Hibernate mapping file for BallPlayer to the Player table (for BallPlayer instances) and associated Uniforms table for the array of ints (the uniformNumbers).  Note the <primitive-array> element.  This is the "magic" for mapping the int[] directly to the Uniforms table.

<hibernate-mapping package="com.intertech.domain">
<class name="BallPlayer" table="Player">
<id name="id">
<generator class="increment" />
</id>
<property name="name" />
<property name="nickname" />
<property name="dob" column="date_of_birth" type="calendar_date" />
<property name="birthCity" column="city_of_birth" />
<primitive-array name="uniformNumbers" table="UNIFORMS">
<key column="PLAYER_ID" />
<index column="ordr" />
<element column="uniform_number" type="int" />
</primitive-array>
</class>
</hibernate-mapping>

Of course, the same mapping can be accomplished with Hibernate annotations.  Depending on the directionality and cardinality, you can find an annotation here to do the same work.

So great question Jason and thanks for bringing it up in class.  If you have questions about Hibernate, please consider attending our Complete Hibernate class.  See Intertech?s full curriculum for other Java topics of interest.

Find Us
Contact Us 651-288-7000 1-800-866-9884
Home | Training | Curriculum | Course Finder | Schedule | Enroll | Twin Cities Java User Group | Consulting | Foundation | Jobs | About Us | Our Story | Press Room | Instructors | President | Map & Directions | Sitemap

Java Training | JSF / Struts / Spring / Hibernate Training | Java Power Tools Training | .NET 4.0 & Visual Studio 2010 Training | Microsoft Web Development Training | Prism / MVVM / MEF Training | .NET 3.5 and Visual Studio 2008 Training | .NET 2.0 and Visual Studio 2003 Training | Cloud Computing Training | Ajax / Web Services / XML Training | Groovy and Grails Training | SQL Server 2012 Training | SQL Server 2008 Training | SQL Server 2005 Training | Mobile Development Training | SharePoint 2010 Training | SharePoint 2007 Training | Agile, Process, Analysis & Design Training | Arch/Design Patterns Training | Microsoft Official Curriculum Training | Web Development Training | Ruby Training | Rational Application Developer (RAD) Training | WebSphere Application Server Training | WebSphere Portal Training | WebLogic Training | Boot Camp Training | Project Management Training | C / C++ Training | Metro / WinRT / Windows 8 Development Training | Retired

Intertech delivers training on-site and virtually serving cities including Phoenix, AZ | San Francisco, CA | Los Angeles, CA | San Diego, CA | San Jose, CA | Washington, DC | Chicago, IL | Orlando, FL | Boston, MA | Duluth, MN | Minneapolis St. Paul, MN | Rochester, MN | Raleigh-Durham, NC | New York, NY | Philadelphia, PA | Austin, TX | Dallas, TX | Houston, TX | Seattle, WA.