openxava / documentation / Lesson 2: Basic domain model - Part 1

Course: 1. Getting started | 2. Basic domain model (1) | 3. Basic domain model (2) | 4. Refining the user interface | 5. Agile development | 6. Mapped superclass inheritance | 7. Entity inheritance | 8. View inheritance | 9. Java properties | 10. Calculated properties | 11. @DefaultValueCalculator in collections | 12. @Calculation and collections totals | 13. @DefaultValueCalculator from file | 14. Manual schema evolution | 15. Multi user default value calculation | 16. Synchronize persistent and computed propierties | 17. Logic from database  | 18. Validating with @EntityValidator 19. Validation alternatives  | 20. Validation on remove  21. Custom Bean Validation annotation  | 22. REST service call from validation  | 23. Attributes in annotations  | 24. Refining the standard behavior | 25. Behavior & business logic | 26. References & collections | A. Architecture & philosophy | B. Java Persistence API | C. Annotations | D. Automated testing

Table of contents

Lesson 2: Basic domain model - Part 1
Domain model
Reference (ManyToOne) as descriptions list (combo)
Annotations
Embeddable
Summary
In this lesson you will start to create the entities required for your project in order to get your invoicing application working.
By now I assume that you know how to create a new entity with OpenXava Studio and how to run the application, because you have already read Lesson1: Getting started, right?

If you don't like videos follow the instructions below.

Domain model

First, we'll create the entities for your invoicing application. The domain model is rather basic, but enough to learn a lot of interesting things:
modeling_en010.png
We'll start with six classes. Later on we'll add a few more to it. Remember that you already have an initial version of Customer and Product.

Reference (ManyToOne) as descriptions list (combo)

Let's start with the most simple case. We are going to create a Category entity and associate it to the Product, displaying it as a combo.
The code for Category entity is:
package com.yourcompany.invoicing.model;
 
import javax.persistence.*;
import org.hibernate.annotations.GenericGenerator;
import org.openxava.annotations.*;
import lombok.*;
 
@Entity @Getter @Setter
public class Category {
 
    @Id
    @Hidden // The property is not shown to the user. It's an internal identifier
    @GeneratedValue(generator="system-uuid") // Universally Unique Identifier (1)
    @GenericGenerator(name="system-uuid", strategy = "uuid")
    @Column(length=32)
    String oid;
 
    @Column(length=50)
    String description;
 
}
It only has an identifier and a description property. In this case we use the Universally Unique Identifier (shown as 1) algorithm to generate the id. The advantage of this id generator is that you can migrate your application to another database (DB2, MySQL, Oracle, Informix, etc) without touching your code. The other id generators of JPA rely on the database to generate the id thereby making them not so portable as UUID.
Execute the Category module and add some categories:
modeling_en035.png
Now, we'll associate Product with Category: Add the next category reference declaration in your Product entity:
public class Product {
 
    ...
 
    @ManyToOne( // The reference is persisted as a database relationship
        fetch=FetchType.LAZY, // The reference is loaded on demand
        optional=true) // The reference can have no value
    @DescriptionsList // Thus the reference is displayed using a combo
    Category category; // A regular Java reference
 
}
This is a plain JPA many-to-one relationship, the one that you can learn more about in appendix B. In this case, thanks to the @DescriptionsList annotation it is displayed as a combo:
modeling_en020.png
Now it's time to complete your Product entity.

Annotations

Product entity at least needs to have attributes such as price, etc. Also it would be nice to have photos and a field for remarks. We are going to use annotations to do that. Annotations are like tags for code, is a form to add metadata to our code, like on variables, methods, classes, packages, etc.
The best way to understand what is an annotation, is to see it in action. Let's add price, photos and remarks properties to your Product entity:
@Money // The price property is used to store money
BigDecimal price;  // BigDecimal is typically used for money

@Files // A complete image gallery is available
@Column(length=32) // The 32 length string is for storing the key of the gallery
String photos;
 
@TextArea// This is for a big text, a text area or equivalent will be used
String remarks;
You have seen how to use annotations. Now you only have to write the annotation and OpenXava will apply special treatment. Execute the module for the Product now, and you will see:
modeling_en040.png
In this case, we use some of the annotations that are included in OpenXava, you can see that each one produces an effect in the user interface.
Some of the annotations available are @Password, @Money, @TextArea, @Label, @DateTime, @Discussion, @Icon, @Telephone, @IP, @EmailList, @MAC , @StringTime, @HtmlText, @Coordinates, @Files, @File, etc. For more information, you can see here, it's talk more about annotations.
Now you have Product ready to use. Let's refine the Customer now.

Embeddable

We are going to add Address to our until now pretty naked Customer. The customer address is not shared by other customers, and when the customer is removed his address is removed too. Therefore we'll model the address concept as an embeddable class in this case. You can learn more about this in appendix B.
Add the Address class to your project:
package com.yourcompany.invoicing.model;
 
import javax.persistence.*;
import lombok.*;
 
@Embeddable // We use @Embeddable instead of @Entity
@Getter @Setter
public class Address {
 
    @Column(length = 30) // The members are annotated as in entity case
    String street;
 
    @Column(length = 5)
    int zipCode;
 
    @Column(length = 20)
    String city;
 
    @Column(length = 30)
    String state;
 
}
You can see how the regular class has been annotated as @Embeddable. Its properties are annotated in the same way as entities, though embeddable classes do not support all functionality of entities.
Now, you can use Address in any entity. Just add a reference to your Customer entity:
public class Customer {
 
    ...
 
    @Embedded // This is the way to reference an embeddable class
    Address address; // A regular Java reference
 
}
The Address data is stored in the same table as the Customer data. And from a user interface perspective you have a frame around address. If you do not like the frame you only have to annotate the reference with @NoFrame thus:
@Embedded @NoFrame // With @NoFrame no frame is shown for address
Address address;
Here's the user interface for an embedded reference with and without @NoFrame:
modeling_en060.png

Summary

In this lesson you have learned how to create references that are displayed with combos with @DescriptionsList, how to use annotations and @Embeddable. Now that we have the basic entities running, it's time to face the core entity of your application, the Invoice entity. Let's do it step by step in the next lesson.

Download source code of this lesson

Any problem with this lesson? Ask in the forum Everything fine? Go to Lesson 3