Creating persistent entities

In this recipe we look at how Spring Roo simplifies the creation of JPA entities using the entity and field commands. In this recipe we'll create a Flight JPA entity which has a composite primary key. Refer to the Creating a many-to-one relationship between entities recipe of Chapter 3, Advanced JPA Support in Spring Roo to see how to create persistent entities with surrogate keys.

The following figure shows the attributes of the Flight entity and its composite primary key (FlightKey):

Creating persistent entities

Getting ready

Exit the Roo shell and delete the contents of the C: oo-cookbookch02-recipes directory.

Execute the ch02_jpa_setup.roo script. It creates a flight-app Roo project and sets up Hibernate as the persistence provider using the persistence setup command. If you are using a different database than MySQL or your connection settings are different from what is specified in the script, then modify the script accordingly.

Start the Roo shell from the C: oo-cookbookch02-recipes directory.

Note

The ch02_persistent_entities.roo script that accompanies this book creates the flight-app project, sets up Hibernate as the persistence provider, modifies the database.username and database.password properties in the database.properties file, and executes the commands shown in this recipe.

How to do it...

The following steps will demonstrate how to create persistent entities:

  1. Create a Flight entity in the sample.roo.flightapp.domain package using the entity command:
    ..roo> entity --class ~.domain.Flight --identifierType ~.domain.FlightKey --table FLIGHT_TBL
    
  2. Add fields to the Flight entity using field commands:
    ..roo> field number --type java.lang.Integer --fieldName numOfSeats
    ..roo> field string --fieldName origin
    ..roo> field string --fieldName destination
    ..roo> field date --type java.util.Date --fieldName createdDate
    ..roo> field date --type java.util.Date --fieldName modifiedDate
    ..roo> field string --fieldName createdBy
    ..roo> field string --fieldName modifiedBy
    
  3. Switch focus to the FlightKey class (that was auto-generated in the sample.roo.flightapp.domain package when we created the Flight entity in Step 1):
    ..roo> focus --class ~.domain.FlightKey
    
  4. Add flightId and departureDate fields to the FlightKey class:
    ..roo> field string --fieldName flightId
    ..roo> field date --fieldName departureDate --type java.util.Date
    

    Tip

    The output of the entity command is not shown above for brevity. We'll discuss the important ITD files generated corresponding to a JPA entity in the How it works... section.

How it works...

The entity command is used to create a JPA persistent entity. It provides a couple of arguments which should be sufficient for most scenarios that you encounter while developing the persistence layer of your enterprise application. For instance, the mappedSuperclass argument marks the class with the @MapperSuperclass JPA annotation (refer to the Creating a mapped superclass recipe in Chapter 3, Advanced JPA Support in Spring Roo), the inheritanceType argument adds the @Inheritance JPA annotation to let you specify the inheritance strategy followed for persisting classes of an inheritance hierarchy, and so on.

The following table describes arguments that you can pass to the entity command:

Argument

Description

class

This is a mandatory argument which specifies the fully-qualified name of the persistent entity class. You can use the '~' symbol while specifying the fully-qualified name.

mappedSuperclass

Instructs Roo that the class is a 'mapped superclass'. If specified, the generated class is annotated with the @MappedSuperclass JPA annotation.

extends

Identifies the superclass of the entity class.

abstract

Specifies that the generated entity is an abstract entity.

inheritanceType

Specifies the inheritance strategy used for persisting the entity. It accepts one of the following values: JOINED, SINGLE_TABLE, and TABLE_PER_CLASS. If specified, it adds the @Inheritance JPA annotation to the entity class.

table

Specifies the name of the table to which the entity is mapped.

identifierField

Specifies the name of the identifier field in the entity. By default the name of the identifier field is id.

identifierType

Specifies the Java type of the identifier field. This argument can accept values pre-defined by Roo, such as java.lang.Long, java.lang.Double, and so on, or it can take a custom Java type.

If your entity uses a composite primary key, then you'll use a custom Java type. For instance, the Flight entity specifies FlightKey as the identifierType because it's the composite primary key class of the Flight entity. Also note that the composite primary key class is auto-generated when you execute the entity command.

identifierColumn

Specifies the table column to which the identifier field is mapped. If your entity uses a composite primary key, then you must not use this argument.

versionField

Specifies the name of the version field in the entity. By default the name of the version field is version.

versionColumn

The table column to which the version field is mapped.

testAutomatically

Instructs Roo to automatically generate integration tests for the entity. In the Creating integration tests for persistent entities recipe we'll discuss integration testing of persistent entities in detail.

schema, catalog

Arguments for specifying qualifiers for table names in the database. These arguments translate into schema and catalog attributes of the @Table JPA annotation.

persistenceUnit

Name of the persistence unit, defined in the persistence.xml file, with which the persistent entity is associated.

transactionManager

[Supported since Spring Roo 1.1.5] Name of the transaction manager which is used for the persistent entity.

You may have noticed that the field command that we have used for adding fields to the Flight JPA entity is the same field command that we had used to add attributes to our Java class in the Adding attributes to a Java class recipe in Chapter 1, Getting Started with Spring Roo.

The following code shows the Flight entity which was created by the entity command:

@RooJavaBean
@RooToString
@RooEntity(identifierType = FlightKey.class, table= "FLIGHT_TBL")
public class Flight {
    private Integer numOfSeats;
    private String origin;
    private String destination;
    ...
}

In the Flight.java code, the @RooJavaBean and @RooToString annotations are the most commonly used Roo annotations. For more information on @RooJavaBean and @RooToString, please refer to the Creating a Java class and Adding attributes to a Java class recipes in Chapter 1, Getting Started with Spring Roo. The @RooEntity annotation provides details about the persistent entity which is the Flight entity in the previous code. The identifierType attribute specifies the identifier type of Flight entity, which is FlightKey—the composite primary key class of the Flight entity. The table attribute specifies the database table to which the Flight JPA entity maps.

Note

You'll notice that the fields of the entity don't use JPA @Column annotation to provide a mapping of the fields to the corresponding FLIGHT_TBL table columns. Later in this recipe we'll see how field command can be used to specify table column mapping for the fields.

The @RooEntity annotation introduces a couple of persistence related methods and attributes using the ITD file, Flight_Roo_Entity.aj, as shown here:

privileged aspect Flight_Roo_Entity {
    declare @type: Flight: @Entity;
    
    declare @type: Flight: @Table(name = "FLIGHT_TBL");
    
    @PersistenceContext
    transient EntityManager Flight.entityManager;
    
    @EmbeddedId
    private FlightKey Flight.id;
    
    @Version
    @Column(name = "version")
    private Integer Flight.version;
    
    public FlightKey Flight.getId() {
        return this.id;
    }
    public void Flight.setId(FlightKey id) {
        this.id = id;
    }
    public Integer Flight.getVersion() {
        return this.version;
    }
    public void Flight.setVersion(Integer version) {
        this.version = version;
    }
    ...
}

The persistence related methods (such as, persist, remove, and so on) have been omitted from the previous code listing for brevity. Auto-generated persistence related methods are discussed in the Controlling auto-generated methods of persistent entities recipe. As you can see, Spring Roo generates the necessary code to create a fully-functional JPA entity.

The following code in Flight_Roo_Entity.aj adds @Table and @Entity JPA annotations in the Flight class:

declare @type: Flight: @Entity;
declare @type: Flight: @Table(name = "FLIGHT_TBL");

In Flight_Roo_Entity.aj, the FlightKey field is annotated with the @EmbeddedId annotation because it is the composite primary key class of the Flight entity. Roo also creates a version field in Flight_Roo_Entity.aj, which maps to the version column of the table to which the Flight entity maps. If we create a persistent entity that doesn't use a composite primary key, then instead of @EmbeddedId, Spring Roo uses the @Id annotation to annotate the primary key.

While generating an entity, Spring Roo also generates a <entity-name>_Roo_Configurable.aj ITD, which is responsible for adding Spring's @Configurable annotation to the entity. Here, <entity-name> is the name of the persistent entity.

The entity instances are typically created outside the Spring's application context by the JPA provider or by using the new operator. The use of @Configurable annotation is particularly useful in entities because it allows injecting beans configured in Spring's application context into the entity instance. It is because of the @Configurable annotation that Spring is able to inject the EntityManager instance into persistent entities.

The following code listing shows the FlightKey class of the flight-app application:

@RooToString
@RooIdentifier
public final class FlightKey {
    private String flightId;
    private Date departureDate;
}

In the code, the @RooIdentifier annotation of Spring Roo is responsible for adding constructors, getter and setter methods for fields, and also provides implementation of the hashCode and equals methods of the FlightKey composite primary key class. Spring Roo generates a <entity-name>_Roo_Identifier.aj ITD file corresponding to the @RooIdentifier annotation on the composite primary key class. Here, <entity-name> is the name of the persistent entity.

The following code shows the methods and attributes defined in the FlightKey_Roo_Identifier.aj ITD file:

privileged aspect FlightKey_Roo_Identifier {
    
  declare @type: FlightKey: @Embeddable;
    
  public FlightKey.new(String flightId, Date departureDate) {}
  private FlightKey.new() {}

  public String FlightKey.getFlightId() {
    return this.flightId;
 }
    
  public Date FlightKey.getDepartureDate() {
    return this.departureDate;
 }
    
  public boolean FlightKey.equals(Object obj) {}
    
  public int FlightKey.hashCode() {}
    
}

In the code, implementation details of methods and constructors have not been shown for brevity. As the code suggests, FlightKey_Roo_Identifier.aj ITD adds the following methods, constructors, fields, and annotations to the FlightKey class:

  • Adds the @Embeddable JPA annotation to the FlightKey class, which is required because the FlightKey class is added to the Flight entity using the @EmbeddedId JPA annotation
  • Adds a no-argument constructor to the FlightKey class
  • Adds a constructor that accepts fields defined in the FlightKey class as arguments
  • Adds getter and setter methods for the fields defined in the FlightKey class
  • Adds implementation for the equals and hashCode methods of the java.lang.Object class

The @RooIdentifier annotation accepts two attributes—gettersByDefault and settersByDefault, which allow you to control the creation of getter and setter methods for the fields defined in the FlightKey class. @RooIdentifier also accepts a third attribute, dbManaged, which is useful if the JPA entity was created by Roo using database reverse engineering. We'll discuss the dbManaged attribute in detail in the Creating entities from a database recipe of Chapter 3, Advanced JPA Support in Spring Roo.

There's more...

We'll now look at how to add fields to persistent entities that contain information about the table columns to which the fields map.

Adding table column information in persistent entity fields

Delete the origin field from the Flight.java file and ensure that Spring Roo is running in the background to remove the origin field from AspectJ ITD files.

Now, add the origin field to the Flight persistent entity using the field command, and specify the name of the table column, FLT_ORIGIN, to which the origin field maps, as the value of column argument:

~.domain.Flight roo> field string --fieldName origin --column FLT_ORIGIN

The presence of the column argument indicates that the field is annotated with the @Column JPA annotation with the value of the column argument representing the value of the name attribute of the @Column annotation, as shown here:

@RooJavaBean
@RooToString
@RooEntity(table = "FLIGHT_TBL")
public class Flight {

    @Column(name = "FLT_ORIGIN")
    private String origin;
}

The Roo script ch02_persistent_fields.roo that accompanies this book contains commands to create the flight-app project consisting of the Flight entity and the FlightKey class. Additionally, the script adds database column mapping for all the persistent fields defined in the Flight entity and FlightKey class. It is recommended that you exit the Roo shell, remove all the files from ch02-recipes directory, and recreate the flight-app Roo project by executing the ch02_persistent_fields.roo script.

The class argument in roo commands

We saw in a couple of recipes that the focus command is used to switch command reference from one class or interface to another class or interface in the Roo project, followed by Roo commands that apply to that class or interface. Instead of using the focus command, you can use the class argument of the roo command (if supported by the roo command) to explicitly specify the class or interface to which the command applies. For instance, we can add a flightId field to FlightKey class without using the focus command, as shown here:

...roo>  field string --class ~.domain.Flight --fieldName origin --column FLT_ORIGIN

As we can see from the field command, we can specify a fully-qualified name of the class on which the command applies.

See also

  • Refer to the Controlling auto-generated methods of persistent entities recipe to see how you can control Spring Roo generated methods corresponding to a persistent entity
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.188.201