Commit 816c4288 authored by Arne Styve's avatar Arne Styve
Browse files

Merge branch 'release/v0.4.1'

parents 6fbcd07e 03704534
......@@ -12,6 +12,7 @@ The project was developed for use in teaching in the course "IDATx2001 Programme
**Version** | **Description**
--------|------------
v0.4.1 | Renamed the class AddressBookDAO to AddressBookDBHandler, since DAO is a general term that also could be used for the AddressBookFileHandler. Also altered slightly the use of EntityManager.
v0.4 | Added Relational Database support, using the embedded Apache Derby server. For details of the changes made, se below.
v0.3 | Adds object serialization of the entire address book.
v0.2 | Added import and export from/to CSV-file. A default CSV-file is provided (Addresses.csv)
......
......@@ -18,6 +18,13 @@
<property name="eclipselink.ddl-generation" value="create-tables"/>
<!-- Alternatives: FINE (logs all SQL), ALL, CONFIG, INFO, WARNING..., OFF -->
<property name="eclipselink.logging.level" value="FINE"/>
<!--
The Database can be pre-filled with entries during startup. This would be very useful during testing
of the application, used in conjunction with "drop-and-create-tables". The SQL-statements for inserting
entries in the DB-table can be stored in a text-file. The line below, when un-commented, will
read SQL-statements from the file "META-INF/sql/data.sql" during application startup.
-->
<!--property name="javax.persistence.sql-load-script-source" value="META-INF/sql/data.sql"/-->
</properties>
......
......@@ -19,7 +19,7 @@ import javafx.scene.layout.GridPane;
import javafx.stage.FileChooser;
import javafx.util.Pair;
import no.ntnu.idata2001.contacts.model.AddressBook;
import no.ntnu.idata2001.contacts.model.AddressBookDAO;
import no.ntnu.idata2001.contacts.model.AddressBookDBHandler;
import no.ntnu.idata2001.contacts.model.AddressBookFileHandler;
import no.ntnu.idata2001.contacts.model.ContactDetails;
import no.ntnu.idata2001.contacts.views.ContactDetailsDialog;
......@@ -212,7 +212,7 @@ public class MainController {
* @return an address book populated by contact details loaded from the database.
*/
public AddressBook loadAddressBookFromDB() {
return new AddressBookDAO();
return new AddressBookDBHandler();
}
/**
......
package no.ntnu.idata2001.contacts.model;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
public class AddressBookDAO implements AddressBook {
// Note the 'transient'-keyword. This is to indicate that these fields
/**
* An addressbook holding contacts, stored in a relational database, implemented using
* the JPA implementation EclipseLink.
* Using the JPA standard for Object Relational Mapping (ORM) removes database specifics
* from the Java code, and hides the underlying RDB solution, making it easy to change between
* different suppliers of Relational Database management Systems (RDBMS), and between locally
* embedded database and server based database systems.
* JPA makes use of <b>EntityManager</b> (EMF) and <b>EntityManagerFactory</b> (EM) classes for
* communication with the underlying RDBMS. Creating an EntityManagerFactory instance is costly:
* </p>
* (<a href="https://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html_single/#d0e980">
* "An entity manager factory is typically create at application initialization time and closed at
* * application end. It's creation is an expensive process."</a>
* </p>
* Hence the EMF is implemented as a field in this class.
*
* <b>NOTE:</b> While the EMF is <b>thread safe</b>, the EM is <b>not thread safe</b>.
*/
public class AddressBookDBHandler implements AddressBook {
// Note the 'transient'-keyword. This is to indicate that this field
// should never be serialized. Since the AddressBook-interface
// implements Serializable (used for object serialisation), this class
// to is tagged to be serializable. But the two fields in this class is used to
// communicate with the database, and should hence not be serialized. Neither are
// the classes EntityManager nor EntityManagerFactory serializable.
// too is tagged to be serializable. But the field in this class is used to
// communicate with the database, and should hence not be serialized.
private final transient EntityManagerFactory efact;
private final transient EntityManager eman;
/**
* Creates an instance of the AddressbookDAO.
*/
public AddressBookDAO() {
public AddressBookDBHandler() {
this.efact = Persistence.createEntityManagerFactory("contacts-pu");
this.eman = efact.createEntityManager();
}
@Override
public ContactDetails findContactByPhoneNumber(String phoneNumber) {
//TODO: To be implemented later....
return null;
}
......@@ -39,9 +56,11 @@ public class AddressBookDAO implements AddressBook {
@Override
public void addContact(ContactDetails contact) {
this.eman.getTransaction().begin();
this.eman.persist(contact);
this.eman.getTransaction().commit();
EntityManager eman = this.efact.createEntityManager();
eman.getTransaction().begin();
eman.persist(contact);
eman.getTransaction().commit();
eman.close();
}
@Override
......@@ -61,6 +80,7 @@ public class AddressBookDAO implements AddressBook {
@Override
public Collection<ContactDetails> getAllContacts() {
EntityManager eman = this.efact.createEntityManager();
List<ContactDetails> contactsList = null;
......@@ -69,17 +89,18 @@ public class AddressBookDAO implements AddressBook {
Query query = eman.createQuery(sql);
contactsList = query.getResultList();
eman.close();
return contactsList;
}
@Override
public void close() {
this.eman.close();
this.efact.close();
}
@Override
public Iterator<ContactDetails> iterator() {
public synchronized Iterator<ContactDetails> iterator() {
return getAllContacts().iterator();
}
}
......@@ -140,8 +140,7 @@ public class ContactDetailsDialog extends Dialog<ContactDetails> {
getDialogPane().setContent(grid);
// Convert the result to ContactDetails-instance when the OK button is clicked.
// Check out: https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Dialog.html#setResultConverter-javafx.util.Callback-
// and: https://docs.oracle.com/javase/8/javafx/api/javafx/util/Callback.html
// Check: https://docs.oracle.com/javase/8/javafx/api/javafx/util/Callback.html
setResultConverter(
(ButtonType button) -> {
ContactDetails result = null;
......
......@@ -32,7 +32,7 @@ import no.ntnu.idata2001.contacts.model.ContactDetails;
*/
public class ContactsApp extends Application {
private static final String VERSION = "0.4";
private static final String VERSION = "0.4.1";
private MainController mainController;
private AddressBook addressBook;
......@@ -61,7 +61,6 @@ public class ContactsApp extends Application {
this.mainController = new MainController();
// Initialise the Address Book from a file
//this.addressBook = this.mainController.loadAddressBookFromFile();
this.addressBook = this.mainController.loadAddressBookFromDB();
}
......@@ -105,8 +104,6 @@ public class ContactsApp extends Application {
*/
@Override
public void stop() {
// Save the address book to file
//this.mainController.saveAddressBookToFile(this.addressBook);
// Exit the application
System.exit(0);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment