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
):
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.
The following steps will demonstrate how to create persistent entities:
Flight
entity in the sample.roo.flightapp.domain
package using the entity
command:..roo> entity --class ~.domain.Flight --identifierType ~.domain.FlightKey --table FLIGHT_TBL
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
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
flightId
and departureDate
fields to the FlightKey
class:..roo> field string --fieldName flightId ..roo> field date --fieldName departureDate --type java.util.Date
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:
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.
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:
@Embeddable
JPA annotation to the FlightKey
class, which is required because the FlightKey
class is added to the Flight
entity using the @EmbeddedId
JPA annotationFlightKey
classFlightKey
class as argumentsFlightKey
classequals
and hashCode
methods of the java.lang.Object
classThe @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.
We'll now look at how to add fields to persistent entities that contain information about the table columns to which the fields map.
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.
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.
3.137.188.201