These are links to resources that describe how to access data via queries in a Spring Boot application. The Spring repository to work with will extend the Crud repository and will include methods that have annotations such as @Query and @Modifying. The queries can use JPQL or be native SQL.
To include HTML or dynamic HTML parts into a Thymeleaf template, Thymeleaf uses the concept and term: “fragments”, which assists with inserting or replacing parts of your pages with other parts. Here is a tutorial: https://www.baeldung.com/spring-thymeleaf-fragments
A Java EE application should be designed with a structure that is easily understandable and makes a balanced use of Data Access Objects, Entities, REST controller, transactions and a database back end. To have the app hosted on WildFly 18.0.1 application server we would require a connection to the database on the server. Below are the basics for the preparation process in order to have a basic application run:
1.
Set up a database. In our example, we set up a database called “WorkSuggest1” and set up a table within the database called “Person”:
When the database is set up, start preparing the WildFly database connector and the data source that will be used in the application. A CLI script can be very useful to have this done. The script below (written by instructors at IT Högskolan Göteborg) helps to set up the module, given that you have the MySQL connector, so keep reading past the script below for more details. The link to the database is also needed. Be sure that the MySQL Connector is in c:\Users folder and the connector version is the one you have.
Normally, a MySQL connector is found in form of a Jar file such as the one found at Jar-download.com, which will accompany a “module.xml” file. To complete the set up, follow a good tutorial on how to set up MySQL database connection on WildFly application server, such as this one.
In general, be sure that you have the database connector, the required module file, and the link to the database set up correctly as they are required for your Java EE application to interact with the database. Some side notes while you are setting them up are:
The connector and the module.xml file should be placed in a directory structure that you create under the “base” folder hierarchy in the WildFly 18 folder structure — more specifically in the folder: C:\wildfly-18.0.1.Final\modules\system\layers\base. Here you will create a “com” folder, add a “mysql” folder there, and in it create a “main” folder. In this main folder you place the mysql connector file as well as the module.xml file.
The module.xml file could have content similar to the one below.
Continue the set up of the database for use via the application server. Given that you will use the CLI script above, place the CLI script in the bin folder of the WildFly 18.0.1 folder, go to the bin folder, and run the script while the server is running. Assuming you are using Windows PowerShell it would be:
.\jboss-cli -c --file=worksuggest1.cli
4.
Upon receiving success message, proceed to setting up the IntelliJ project which should have a Maven.pom.xml file with dependencies as described in the below pom.xml file:
A file structure such as the one shown below can help with the development of the project with respective Java EE concepts considered:
7.
The complete and working project (given that the MySQL database is available and the WildFly 18.0.1 application server are running) is included in the zip file below.
There are many JSON libraries that make JSON works possible in a Java application. When responding HTTP response that should be in JSON format we should use the annotation:
@Produces(MediaType.APPLICATION_JSON)
With the Http Methods Get, Post, Delete, Put and Patch, we should consider the respective annotation, i.e. @GET, @POST, @DELETE, @PUT and @PATCH.
Since it is desirable that RESTful Java apps reply through JSON objects, we do responses in JSON format.
One way would be to write a String variable but use the curly brackets and backslashes as in
Java applications using the Jersey implementation for RESTful Java apps can use the Jersey media dependency. More reading on this can be found at: https://code.i-harness.com/en/q/120cba9 where we see that the right Maven dependency can help in returning JSON objects from Java variables:
For example to return a List variable in JSON format using the above dependency, we can write code where we use the @POST annotation, prepare a list of persons and return via Response.ok(persons).build.
@POST
@Path("/all")
@Consumes(MediaType.APPLICATION_JSON)
@Produces({MediaType.APPLICATION_JSON})
public Response all() {
Person p1 = new Person (1, "Bob", "bob@test.com", "0123456789", "123 Main St.");
Person p2 = new Person (2, "Bob2", "bob@example.com", "0987654321", "456 Main St.");
Person p3 = new Person (3, "Bob3", "bob@company.com", "0700123456", "789 Main Street");
List<Person> persons = new ArrayList<Person>();
persons.add(p1);
persons.add(p2);
persons.add(p3);
//good resources:
// https://stackoverflow.com/questions/41761082/convert-list-to-jsonobject-in-java-using-json-simple
//https://code.i-harness.com/en/q/120cba9 //java - webservices - jersey return arraylist json
System.out.println("List: " + persons);
return Response.ok(persons).build(); //this works
//return Response.ok().entity(persons).build(); //this works also
}
}
To run the project on a local server, “Edit Configuration” under the “Run” menu. Set up a configuration based on a local server that you have, for example a local “Tomcat Server”, version 8.5.50. There will be a red icon on the “Fix” button on the bottom right corner, which can be clicked with an option “war exploded” selected. Clicking “Ok” adds configuration.
Find the “webapp” folder under the main root of the project which holds the “WEB-INF” folder. In this folder, update or create the “web.xml” file to specify the servlet name, init-param detail, and servlet-mapping detail, for example like the example below:
Create the “resources” folder under src/main folder, and create or have the “META-INF” folder. Ceate your persistence.xml file there. Here is a persistence.xml file example:
Although one or two tutorials can lead to the answer in how to write code for entities that hold bidirectional relationship, here is a suggest set of links and descriptions that can help:
Database interactions in a Java EE application are done through JPA.
JPA is a specification that defines the management of relational data in a Java application.
JPA is a specification and needs an implementation
JPA has concepts that an implementation must cover.
Entity through the javax.persistence.Entity class
Field Persistence All fields in the object are persisted unless annotated with @Transient.
Relationships JPA specifies how we should manage relationships between different database tables. @OneToOne, @OneToMany, @ManyToOne, @ManyToMany
EntityManager through the javax.persistence.EntityManager class — EntityManager contains common Create, Read, Update and Delete (CRUD) operations that are “persisted” to the database.
JPA has implementations available such as Hibernate and EclipseLink. Otherwise there is a lot of code to write classes for the above. Benchmarks for the implementations are available. Hibernate is one of the mature implementations (described below). EclipseLink is another implementation, which is open source, supports a number of other persistence standards such as Java Architecture for XML Binding (JAXB) and has an XML Representation. EclipseLink has extensions of its own such as @ReadOnly, @Struct while not having an annotation such as @BatchSize which is featured in Hibernate.
Steps for a Maven JPA application with its persistence dependencies are as below.
Create the POJO entities classes
Add the dependencies to the pom.xml file. Artifact IDs are:
javax.persistence
hibernate-entitymanager
mysql-connector-java
set up persistence.xml file in META-INF folder
run a test class
Notes about POJO classes while developing with JPA
the class should implement java.io.Serializable
POJO entity classes that have fields with one-to-many relationships should be annotated by the annotations that show the relationship. Some of these annotations are @OneToMany and @ManyToOne, @JoinColumn, @mappedBy. A bidirectional relationship between two tables would have annotations @OneToMany and @ManyToOne.
if the primary key “id” of the entity class does not have the annotation @GeneratedValue(strategy=GenerationType.AUTO) then one can run the EntityManager’s persist with the entity class that assigns id manually. However, if the primary key “id” has the annotation @GeneratedValue(strategy=GenerationType.AUTO) then entity manager’s persist can be used with a persist that does not have the id included.
Other resources through out the development (in order of occurrence):
error: org.hibernate.PersistentObjectException: detached entity passed to persist. A Stackoverflow solution starts with the question and issue that rises in situations: “I had successfully written my first master child example with hibernate. After few days I took it again and upgraded some libraries. No sure what I did I do but I could never make it run again. Would somebody help my figure out what is wrong in code that is returning following error message: …”
Working with databases from a Java EE application requires understanding of the SQL database tables design. The design which includes table naming, table fields naming, field types and other well-thought-out design elements described by database administrators also includes how the relationship between the various tables works.
It is much better to design the tables with the right structure at first place rather than altering later. Otherwise altering a table would require SQL queries that sometimes take more time to figure out.
Three alteration examples for a MySQL Database table would be:
-- make "id" field in "tasks" table primary:
ALTER TABLE tasks ADD CONSTRAINT pk_id PRIMARY KEY (id);
-- add auto increment to field in "tasks" table:
ALTER TABLE tasks AUTO_INCREMENT=0;
-- rename column name "id" to "taskStatus_id":
ALTER TABLE task RENAME COLUMN id TO taskStatus_id;
Relationships between tables can be designed through fields that connect one table to the other. Let’s say for example that we design two tables, one called “tasks” and the other called “taskstatus” with a relationship. table A would have fields “id”, “topic”, “description”, “parent_status” and table “taskstatus” holds fields “id”, “status”, “description”. The field “parent_status” of “tasks” table would reference “status” in the “taskstatus” table since we are planning to have our list of task status such as “to do”, “done”, “doing” in its own table.
Relationships that may help us design a better database and application would include one-to-one, one-to-many, and many-to-many relationship between table fields. For these to work the fields should have certain constraints. For a MySQL one-to-many relationship to work, for example, the field that is being referenced in the parent table should either be PRIMARY or UNIQUE.
The completed tables’ SQL structure for our two tables is as follows:
CREATE TABLE taskstatus (
id INT NOT NULL AUTO_INCREMENT,
status VARCHAR(255) UNIQUE,
description VARCHAR(255),
PRIMARY KEY(id)
) ENGINe=INNODB;
CREATE TABLE task (
id INT NOT NULL AUTO_INCREMENT,
topic VARCHAR(255),
parent_status VARCHAR(255),
description VARCHAR(255),
INDEX tasksstatus_ind (parent_status),
PRIMARY KEY(id),
FOREIGN KEY(parent_status) references taskstatus(status) ON DELETE CASCADE
) ENGINE=INNODB;
Now that the tables are ready we can add data:
-- insert an item to the parent table "taskstatus" that holds UNIQUE status
INSERT INTO taskstatus (id, status, description) VALUES (1, "to do", "");
-- now that a "status" is available in the parent table, we can add a task that uses the status we mentioned in order to insert a task with the "status" foreign key value.
INSERT INTO tasks (id, topic, parent_status, description) VALUES(2,"clean garden","to do", "");
To add a record which has a foreign key we can use the SQL code syntax below:
INSERT INTO tasks(topic, parent_status)
SELECT 'put books on the shelf',
status FROM taskstatus
WHERE
status='to do' LIMIT 1;
Understanding SQL Table relations help design an application with consideration for foreign keys and the SQL statements required when interacting with the database.
Here are useful reads on application servers which host Java EE applications.
Is Tomcat an application server? This article describes what is meant by the term Application Server when it comes to Java application hosting and Tomcats roll.