Information Systems FHNW Pre-Master Information Systems 3. Persistence Layer Andreas Martin 3. Persistence Layer http://www.flickr.com/photos/shandrew/3327258963
of information, processing / forwarding of user interactions. Technologies: JavaServer Faces (JSF), JavaServer Pages (JSP), Servlets, etc. Business (Logic) Layer Goal: Reproduction of actions or «verbs» of the application (buy a book, print an order, deliver a book, etc.). Technologies: Enterprise Java Beans (EJBs) Persistence Layer Goal: Reproduction of database attributes, information or «nouns» in object / class attributes (Object-Relational Mapping, ORM). Technologies: Java Persistence API (JPA)
declares a database relation. @Id: defines the primary key value(s). @GeneratedValue: defines a value the will be automatically generated. @Column: can be used to modify the standard mapping behaviour. 3. Persistence Layer Listing: A Simple Book Entity @Entity public class Book { @Id @GeneratedValue private Long id; @Column(nullable = false) private String title; private Float price; @Column(length = 2000) private String description; private String isbn; private Integer nbOfPage; private Boolean illustrations; // Constructors, getters, setters } Adapted from: Goncalves: Code and Models licensed under a CC BY-SA 3.0 License from https://github.com/agoncal/agoncal-book-javaee7
Entity 3. Persistence Layer Listing: Simple Example of a Book Entity @Entity public class Book { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String title; private Float price; private String description; private String isbn; private Integer nbOfPage; private Boolean illustrations; public Book() { } // Getters, setters } Adapted from: Goncalves: Code and Models licensed under a CC BY-SA 3.0 License from https://github.com/agoncal/agoncal-book-javaee7
Entity 3. Persistence Layer Listing: Simple Example of a Book Entity @Entity public class Book { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String title; private Float price; private String description; private String isbn; private Integer nbOfPage; private Boolean illustrations; public Book() { } // Getters, setters } Listing: Structure of the BOOK Table CREATE TABLE BOOK ( ID BIGINT NOT NULL, TITLE VARCHAR(255), PRICE DOUBLE(52, 0), DESCRIPTION VARCHAR(255), ISBN VARCHAR(255), NBOFPAGE INTEGER, ILLUSTRATIONS SMALLINT, PRIMARY KEY (ID) ); Adapted from: Goncalves: Code and Models licensed under a CC BY-SA 3.0 License from https://github.com/agoncal/agoncal-book-javaee7
EntityManager 3. Persistence Layer EntityManagerFactory emf = Persistence.createEntityManagerFactory("primary"); EntityManager em = emf.createEntityManager(); em.persist(book); The methods persist() and find() will be transferred by the EntityManager into JDBC calls (INSERT or SELECT SQL statements). Adapted from: Goncalves: Code and Models licensed under a CC BY-SA 3.0 License from https://github.com/agoncal/agoncal-book-javaee7
@Entity @NamedQuery(name = "findBookWithTitleJava", query = "SELECT b FROM Book b WHERE b.title =‘Java'") public class Book { @Id @GeneratedValue private Long id; @Column(nullable = false) private String title; private Float price; @Column(length = 2000) private String description; private String isbn; private Integer nbOfPage; private Boolean illustrations; // Constructors, getters, setters } Querying Entities using JPQL and EntityManager Instead of using native SQL, it is more sophisticated to use JPQL: SELECT b FROM Book b WHERE b.title = ‘Java‘; JPQL is similar to SQL, which adds the object-point notation. 3. Persistence Layer Adapted from: Goncalves: Code and Models licensed under a CC BY-SA 3.0 License from https://github.com/agoncal/agoncal-book-javaee7
@ GitHub …will be used for all the hands-on’s 1. First download “Hands-on Projects @ GitHub” ZIP- file from Moodle and extract it into a folder. 2. Import predefined projects in Eclipse: 3. Persistence Layer
we know what an entity or the entity manager is. In this hands-on we are going to write a small application, which stores an entity into a database. Create a Book entity and a Main class including a main method, that stores a book entry into our MySQL database (use the premscis scheme). Use the predefined maven project and watch out the pre- configurations. 3. Persistence Layer
create from blueprint) the hands-on-1 project. All the source code will be placed into the ch.fhnw.mscbis.premscis.handson1 package. 2. Create a Book entity with the following attributes: id, title, price, description, isbn, numberOfPages and illustrations. Choose the right datatypes. 3. Generate Getter & Setter methods. 3. Persistence Layer
Main class and a main method where you create a book. 3. Persistence Layer // Create a book EntityManagerFactory emf = Persistence.createEntityManagerFactory("primary"); EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); em.persist(book); tx.commit(); em.close(); emf.close();
is used to define the name of the database table. Btw.: @javax.persistence.Table would be the full path to the annotation, we can use the short form in combination with an include. 3. Persistence Layer Listing: The Book Entity Being Mapped to a T_BOOK Table @Entity @Table(name = "t_book") public class Book { @Id private Long id; private String title; private Float price; private String description; private String isbn; private Integer nbOfPage; private Boolean illustrations; public Book() { } // Getters and setters } Adapted from: Goncalves: Code and Models licensed under a CC BY-SA 3.0 License from https://github.com/agoncal/agoncal-book-javaee7
3. Persistence Layer Listing: DDL of the NEWS Table with a Composite Primary Key create table NEWS ( CONTENT VARCHAR(255), TITLE VARCHAR(255) not null, LANGUAGE VARCHAR(255) not null, primary key (TITLE, LANGUAGE) ); Listing: The Entity Embeds the Primary Key Class with @EmbeddedId @Entity public class News { @EmbeddedId private NewsId id; private String content; // … } Listing: The Primary Key Class Is Annotated with @Embeddable @Embeddable public class NewsId { private String title; private String language; // … } Adapted from: Goncalves: Code and Models licensed under a CC BY-SA 3.0 License from https://github.com/agoncal/agoncal-book-javaee7
Adapted from: Goncalves: Code and Models licensed under a CC BY-SA 3.0 License from https://github.com/agoncal/agoncal-book-javaee7 Annotation Direction @OneToOne Unidirectional @OneToOne Bidirectional @OneToMany Unidirectional @ManyToOne / @OneToMany Bidirectional @ManyToOne Unidirectional @ManyToMany Unidirectional @ManyToMany Bidirectional All possible mappings:
Listing: The Order Entity with a Join Column @Entity public class Order { @Id @GeneratedValue private Long id; @Temporal(TemporalType.TIMESTAMP) private Date creationDate; @OneToMany(fetch = FetchType.EAGER) @JoinColumn(name = "order_fk") private List<OrderLine> orderLines; // Constructors, getters, setters } Listing: An OrderLine @Entity @Table(name = "order_line") public class OrderLine { @Id @GeneratedValue private Long id; private String item; private Double unitPrice; private Integer quantity; // Constructors, getters, setters } Adapted from: Goncalves: Code and Models licensed under a CC BY-SA 3.0 License from https://github.com/agoncal/agoncal-book-javaee7
write 3. Persistence Layer Listing: One Artist Appears on Several CD Albums @Entity public class Artist { @Id @GeneratedValue private Long id; private String firstName; private String lastName; @ManyToMany(cascade = CascadeType.ALL) @JoinTable(name = "jnd_art_cd", joinColumns = @JoinColumn(name = "artist_fk"), inverseJoinColumns = @JoinColumn(name = "cd_fk")) private List<CD> appearsOnCDs; // Constructors, getters, setters } Listing: One CD is Created by Several Artists @Entity public class CD { @Id @GeneratedValue private Long id; private String title; private Float price; private String description; @ManyToMany(cascade = CascadeType.ALL) @JoinTable(name = "jnd_art_cd", joinColumns = @JoinColumn(name = "cd_fk"), inverseJoinColumns = @JoinColumn(name = "artist_fk")) private List<Artist> createdByArtists; // Constructors, getters, setters } Adapted from: Goncalves: Code and Models licensed under a CC BY-SA 3.0 License from https://github.com/agoncal/agoncal-book-javaee7
Persistence Layer Listing: A Main Class Persisting and Retrieving a Book Entity public class Main { public static void main(String[] args) { // 1-Create an instance of the Book entity Book book = new Book(); book.setId(1234L); book.setTitle("The Hitchhiker's Guide to the Galaxy"); book.setPrice(12.5F); book.setDescription("Science fiction created by Douglas Adams."); book.setIsbn("1-84023-742-2"); book.setNbOfPage(354); book.setIllustrations(false); // 2-Get an entity manager and a transaction EntityManagerFactory emf = Persistence.createEntityManagerFactory(«primary"); EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); // 3-Persist the book to the database tx.begin(); em.persist(book); tx.commit(); // 4-Retrieve the book by its identifier book = em.find(Book.class, 1234L); System.out.println(book); em.close(); emf.close(); } } Adapted from: Goncalves: Code and Models licensed under a CC BY-SA 3.0 License from https://github.com/agoncal/agoncal-book-javaee7
Layer Listing: Persisting a Customer with an Address EntityManager em = …; Customer customer = new Customer("Antony", "Balla", "[email protected]"); Address address = new Address("Ritherdon Rd", "London", "8QE", "UK"); customer.setAddress(address); tx.begin(); em.persist(customer); em.persist(address); tx.commit(); assertNotNull(customer.getId()); assertNotNull(address.getId()); Adapted from: Goncalves: Code and Models licensed under a CC BY-SA 3.0 License from https://github.com/agoncal/agoncal-book-javaee7
variable>] SET <update statement> {, <update statement>}* [WHERE <conditional expression>] DELETE FROM <entity name> [[AS] <identification var.>] [WHERE <conditional expression>] JPQL SELECT- Syntax DELETE- Syntax UPDATE- Syntax The JPQL syntax is comparable to the SQL syntax is used in a MySQL or Apache Derby environment. Extensions in JPQL e.g.: 3. Persistence Layer Source: Goncalves, 2010: Beginning Java™ EE 6 Platform with GlassFish™ 3 – Code (Apache-2.0 license): http://kenai.com/projects/beginningee6/ SELECT <expression> FROM <clause> [WHERE <conditional expression>] [ORDER BY <clause>] [GROUP BY <clause>] [HAVING <clause>] SELECT CASE b.author WHEN 'Martin' THEN b.price * 1.5 ELSE b.price * 0.8 END FROM Book b
like Dynamic Queries: Query query = em.createNamedQuery("findAll"); List<Customer> customers = query.getResultList(); as Named Typed Query: TypedQuery<Customer> query = em.createNamedQuery("findAll", Customer.class); List<Customer> customers = query.getResultList(); and including parameters Query query = em.createNamedQuery("findWithParam"); query.setParameter("fname", "Vincent"); List<Customer> customers = query.getResultList(); 3. Persistence Layer Listing: The Customer Entity Defining Named Queries @Entity @NamedQueries( { @NamedQuery(name = "findAll", query="select c from Customer c"), @NamedQuery(name = "findVincent", query="select c from Customer c where c.firstName = 'Vincent'"), @NamedQuery(name = "findWithParam", query="select c from Customer c where c.firstName = :fname") }) public class Customer { @Id @GeneratedValue private Long id; private String firstName; /* etc. */ } Adapted from: Goncalves: Code and Models licensed under a CC BY-SA 3.0 License from https://github.com/agoncal/agoncal-book-javaee7
«hands-on-2» project. 2. Create the following entities: Address and Customer Fields of Address: id, street1, city, zipcode und country. Fields of Customer: id, firstName, lastName, email und address. Please give the entities a unique table name. 3. Write a main method in a Main class and enter some data into the database. 3. Persistence Layer