I tested to use a cloud Postgres database provided by Heroku from my Netbeans in the following database connection setup. However, it led to a connection failure.
I think the fault should be at the JDBC URL, which needs extra string to break down the https. Please ref. to how-to-connect-postgres-database
# DATA SOURCE
spring.datasource.url=jdbc:postgres://ixfctradvatvsx:s5d2njfvukfHWlzdmVDcETNUgx@ec2-54-83-56-177.compute-1.amazonaws.com:5432/dlbp7q8itvcdf
spring.datasource.username = ixfctradvatvsx
spring.datasource.password = s5d2njfvukfHWlzdmVDcETNUgx
spring.datasource.driver-class-name = org.postgresql.Driver
# JPA/HIBERNATE
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = create-drop
spring.jpa.database-platform = org.hibernate.dialect.PostgreSQLDialect
Sunday, 30 April 2017
Saturday, 22 April 2017
org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: Infinite recursion
When retrieving an object via remote http request. Getting following error:
Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: Infinite recursion
The JSON response becomes incredible huge. This happens when two entities have a bi-directional relationship. The owning side needs to keep foreign key pointing to its associated entity. This may result in recursive references. On this case, it needs to close its JSON serialization.
Using @JsonIgnoreProperties, it works at the class level. Note: It is different from @JsonIgnore, for it works at the field and property level.
The following example is the solution for the exception above. At the owning side:
Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: Infinite recursion
The JSON response becomes incredible huge. This happens when two entities have a bi-directional relationship. The owning side needs to keep foreign key pointing to its associated entity. This may result in recursive references. On this case, it needs to close its JSON serialization.
Using @JsonIgnoreProperties, it works at the class level. Note: It is different from @JsonIgnore, for it works at the field and property level.
The following example is the solution for the exception above. At the owning side:
/** * * @author YNZ */ @Entity @Table(name = "YARD") @JsonIgnoreProperties(value = {"lister", "searcher"}, allowSetters = true) public class Yard implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "YARD_ID_PK") @JsonIgnore protected long id; @Column(name = "NAME") protected String name; @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name = "ADDRESS_ID_FK", referencedColumnName = "ADDRESS_ID_PK") protected Address address; //owning side keeping FK @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name = "Lister_ID_FK", referencedColumnName = "USER_PK") protected Lister lister; @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name = "SEARCHER_ID_FK", referencedColumnName = "USER_PK") protected Searcher searcher;At inverse side:
/** * * @author YNZ */ @Entity @Table(name = "LISTER") //@JsonIgnoreProperties(value = "listedYard", allowSetters = true) public class Lister extends User { @OneToOne(mappedBy = "lister", cascade = CascadeType.ALL, targetEntity = Yard.class) //inverse side private Yard listedYard; public Lister() { } public Yard getListedYard() { return listedYard; } public void setListedYard(Yard listedYard) { this.listedYard = listedYard; } }
Friday, 21 April 2017
Spring with JUnit
Testing Controllers
@Runwith(SrpingRunner.class)
@Runwith(SrpingRunner.class)
@WebMvcTest(SpecificController.class)
@ContextConfiguration defines class-level metadata that is used to determine how to load and configure an ApplicationContext for integration tests.
How to plan to test @Service components. It is the location of business logic, and typically the priority of the test.
@DataJpaTest
Integration test
It includes all dependencies, and provides a full servlet engine behaviour; meanwhile, load @Controllers,@Services and @Repository;
@Runwith(SrpingRunner.class)
@SpringBootTest(WebEnvironment =RANDOM_PORT); it provides a real servlet container.
@ContextConfiguration defines class-level metadata that is used to determine how to load and configure an ApplicationContext for integration tests.
@ActiveProfiles("dev")
@Configuration
@Profile("dev")
public class StandaloneDataConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.addScript("classpath:com/bank/config/sql/test-data.sql")
.build();
}
}
Testing Services
How to plan to test @Service components. It is the location of business logic, and typically the priority of the test. Which type of test is needed? Unit test? Integration test? Both?
Every component should be involved in an integration test.
Not load @Controllers, Only load @Service; connecting to a real data source-test-specific or another staging.
@Runwith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvment.NONE)
It means there is no need to include a servlet dispatcher, a servlet container, and controllers for testing @Service layer.
Difference between @Mock and @MockBean
@Mock comes from Mockito framework; @RunWith(MockitoJUnitRunner.class)
@MockBean comes from SpringBoot. @RunWith(SrpingRunner.class)
@ExtendWith(SpringExtension.class)Integrating Spring test context with the JUnit 5.
Testing Data Acess
There is no too much achieved from a unit test on the repository layer, so focusing on the integration test.
@Runwith(SpringRunner.class)
it marks the unit test using the Junit4 framework.
it marks the test specific to the data access layer. Only loading repository components.
@AutoConfigureTestDatabase
It is applied to a test class to configure a test database to use instead of any application-defined or auto-configured DataSource.
@TestExecutionListeners
@DatabaseSetup
@DataJpaTest magic explained:
- @AutoConfigureDataJpa: imports all configuration(components) needed for JPA testing.
- @AutoConfigureTestDatabase(replace=Replace.NONE): allow to specify what type of database is used for the test; using an embedded database or pointing to another database external or staging; or a default database already found on the classpath;
- @AutoConfigureTestEntityManager: allowing to access the EntityManager.
- @Transactional: AOP around the method scope.
- more ...
DBUnit framework:
DBUnit is another unit test framework in the Java ecosystem that focuses on aiding the ability to test data access code.
- Created a DBUnit dataset, in XML
- Combined features of Junit and DBUnit frameworks.
- Creating data scenario without creating date entity classes.
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>2.5.0</version>
<type>jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.springtestdbunit</groupId>
<artifactId>spring-test-dbunit</artifactId>
<version>1.2.0</version>
<scope>test</scope>
</dependency>
Creating integration test datasets:
Instruct JUnit to do the following:
not load @Controllers,@Services
Load @Repository and related dependencies
Example:@Entity
Load JPA testing configurations
Load DBUnit testing configuration and dataset, in XML
Test Suites
Smoke Tests: tests that indicate basic system health.
Iteration Suite: tests that are related to a project iteration.
Feature Suite: Tests that combine testing of several features.
@RunWith(Suite.class)
@Suite.SuiteClasses(
{TestA.class, TestB.class}
)
The CI server test suite shows the following:
- A systems health check
- Example: database
- Settled feature integration test
- Extensible and flexible overall application architectures status check.
SpringBoot Test
@SpringBootTest provides features like the followings:
- Automatically searches for a @SpringBootConfiguration when nested @Configuration class is not used, and no explicit classes are specified.
- Allows custom env. properties to be defined using the properties attributes.
- Provides support for different web environment modes, including the ability to start a fully running web server listening on a defined or random port.
- Registers a TestRestTemplate and/or WebTestClient bean for use in web tests that are a fully running web server.
Using @SpringBootTest for integration testing
SpringBoot integration test: Spring framework offers a way to wire up loose coupling components within an embedded servlet container, and enabled automated configuration, which is also called the Spring Application Context. In such a sandbox, a developer may test his unit test cases(JUnit), such as sending an Http request to web-service methods and connecting to a database(maybe in memory).
Since Spring 3.2, Spring Mock MVC framework provides a test context. It simulates a servlet container, where an HTTP request can be launched and handled by the controller. By this way, a controller can be tested as if it is running a production server.
In order to initiate a SpringBoot unit test, you need adding following two annotations on a test class.
@RunWith(SpringRunner.class) it bridges JUnit 4
@SpringBootTest a number of other annotations are also provided for testing more specific slices of an application. The @SpringBootTest annotation tells Spring Boot to go and look for the main configuration class (one with @SpringBootApplication for instance), and use that to start a Spring application context.
You can use the webEnvironment attribute of @SpringBootTest to further refine how your tests will run:
The classes attribute specifies the annotated classes to use for loading an ApplicationContext.
@SpringBootTest classes attribute usage
Since Spring 3.2, Spring Mock MVC framework provides a test context. It simulates a servlet container, where an HTTP request can be launched and handled by the controller. By this way, a controller can be tested as if it is running a production server.
@RunWith(SpringRunner.class) it bridges JUnit 4
@SpringBootTest a number of other annotations are also provided for testing more specific slices of an application. The @SpringBootTest annotation tells Spring Boot to go and look for the main configuration class (one with @SpringBootApplication for instance), and use that to start a Spring application context.
You can use the webEnvironment attribute of @SpringBootTest to further refine how your tests will run:
- MOCK — Loads a WebApplicationContext and provides a mock servlet environment. Embedded servlet containers are not started when using this annotation. If servlet APIs are not on your classpath this mode will transparently fall back to creating a regular non-web ApplicationContext. Can be used in conjunction with@AutoConfigureMockMvc for MockMvc-based testing of your application.
- RANDOM_PORT — Loads an EmbeddedWebApplicationContext and provides a real servlet environment. Embedded servlet containers are started and listening on a random port.
- DEFINED_PORT — Loads an EmbeddedWebApplicationContext and provides a real servlet environment. Embedded servlet containers are started and listening on a defined port (i.e from your application.properties or on the default port 8080).
- NONE — Loads an ApplicationContext using SpringApplication but does not provide any servlet environment (mock or otherwise).
Using @SpringBootTest for unit testing
'Classes' attribute:
@SpringBootTest classes attribute usage
@SpringBootTest
(classes = {EmployeeRepository.
class
, EmployeeService.
class
})
public
class
SpringBootDemoApplicationTests
{
@Autowired
private
EmployeeService employeeService;
//---- tests -----
}
References
Spring Boot Hello World Example – Mustache
What is the difference between @Before and @BeforeClass annotations?
@Before
public void method()
TheBefore
annotation indicates that this method must be executed before each test in the class, so as to execute some preconditions necessary for the test.@BeforeClass
public static void method()
TheBeforeClass
annotation indicates that the static method to which is attached must be executed once and before all tests in the class. That happens when the test methods share computationally expensive setup (e.g. connect to database).
Monday, 17 April 2017
Tuesday, 11 April 2017
JPA
ref. to Spring Data JPA
Special feathers
1. Spring Query DSL Data Extension
Benefits of Using JPA
1. Productive, cardinality relationships.
2. Independent of underly database diabetes. Increasing code portabilities.
3. Caching. free to have. cache holding all entities, and maintain transactions.
4. JPA may generate efficient SQL queries
Persistence
'Persistence' means that the data may be physically stored for retrieving, processing, transforming, or analyzing even the application life cycle has reached the end of the life cycle.
ORM
Java data model is created according to the object-oriented principle. However, in the database, all tables are related to each other via foreign keys and cardinality relationships.
ORM is about how mapping a Plain Java Old Object (POJO) into a relational database table. One object(instance) stands for a row in a database table. Its attributes are persisted into table columns, excluding ones modified by 'transient'.
Entities
An entity class is a POJO decorated by annotation @Entity. It must follow the following requirements.
Entity relationships(cardinality) are used to describe the instance relationships like one customer may have many orders, one customer must have one address, or one student is enrolled in many courses, meanwhile, a course may be registered by many students, etc.
@OneToOne(owning side can be any side)
@OneToMany and @ManyToOne(owning side at many)
@ManyToMany(@JoinTable)
Fetch types: lazy or eager.
to-one is by default eager.
to-many is by default lazy.
@JoinColumn (owning side, keeping the foreign reference.)
@Mapped (inverse side)
Instance relationship may be bidirectional or unidirectional, describing the dependencies of instances. For a bidirectional relationship, both instances are able to access each other. So they both need to keep a reference that points to another. For a unidirectional relationship, only one side of both instances needs to access the instance at the anther side.
How these instance relationships are mapped into relational database tables?
For bidirectional instance relationships: a designer must know which entity keeps the foreign key. It is called the owning side, thus the opposite side is called the inverse side.
Owning side is annotated by @JoinColumn. It declares a column to store a foreign key, which points to the inverse side. It is also called Children points to the Parrent.
Inverse side is annotated by @OneToMany(mappedBy = "propertyNameAtOwningSide")
mappedBy means its reference is kept at the owning side as a foreign key.
Persistence Context
The persistence context is a set of entity instances, which are accessed via an interface, an entity manager. We may manage underlying entities using this interface. The persistence context serves as a first-level cache, buffering the entity instances.
Within the persistence context, the entity instances' lifecycle is managed. An entity instance has four states, i.e. new, managed, removed, or detached.
New state: when an entity is instantiated at the application. It enters the new state.
Managed state: when the instance is persisted, it becomes managed in the persistence context.
Removed state: when the entity instance is set to be removed, after flushing, its counterpart is deleted from the DB.
Spring Data
1. Spring Query DSL Data Extension
Benefits of Using JPA
1. Productive, cardinality relationships.
2. Independent of underly database diabetes. Increasing code portabilities.
3. Caching. free to have. cache holding all entities, and maintain transactions.
4. JPA may generate efficient SQL queries
Persistence
'Persistence' means that the data may be physically stored for retrieving, processing, transforming, or analyzing even the application life cycle has reached the end of the life cycle.
ORM
Java data model is created according to the object-oriented principle. However, in the database, all tables are related to each other via foreign keys and cardinality relationships.
ORM is about how mapping a Plain Java Old Object (POJO) into a relational database table. One object(instance) stands for a row in a database table. Its attributes are persisted into table columns, excluding ones modified by 'transient'.
Entities
An entity class is a POJO decorated by annotation @Entity. It must follow the following requirements.
- It is not inherited from any framework class or interface.
- The class must be annotated with the Entity annotation.
- The class must have a public or protected, no-argument constructor. The class may have other constructors.
- The class must not be declared final. No methods or persistent instance variables must be declared final.
- If an entity instance is passed by value as a detached object, such as through a session bean’s remote business interface, the class must implement the Serializable interface.
- ?It may be an abstracted class, which is persisted by its derivatives
- ?An entity may be extended from an abstract class; abstract class will be a part of the table.
- ?An entity may be extended from another entity.
- An entity may be extended from a non-entity class, but the non-entity class is not included in the table.
- An entity may be extended from a non-entity class but decorated by annotation @MappedSupperClass. The superclass will be included as a part of the table.
- Instance attributes must be declared as private, protected, or package-private and can be accessed directly only by the entity class’s getters and setters.
Entity relationships(cardinality) are used to describe the instance relationships like one customer may have many orders, one customer must have one address, or one student is enrolled in many courses, meanwhile, a course may be registered by many students, etc.
@OneToOne(owning side can be any side)
@OneToMany and @ManyToOne(owning side at many)
@ManyToMany(@JoinTable)
Fetch types: lazy or eager.
to-one is by default eager.
to-many is by default lazy.
@JoinColumn (owning side, keeping the foreign reference.)
@Mapped (inverse side)
Instance relationship may be bidirectional or unidirectional, describing the dependencies of instances. For a bidirectional relationship, both instances are able to access each other. So they both need to keep a reference that points to another. For a unidirectional relationship, only one side of both instances needs to access the instance at the anther side.
How these instance relationships are mapped into relational database tables?
For bidirectional instance relationships: a designer must know which entity keeps the foreign key. It is called the owning side, thus the opposite side is called the inverse side.
Owning side is annotated by @JoinColumn. It declares a column to store a foreign key, which points to the inverse side. It is also called Children points to the Parrent.
Inverse side is annotated by @OneToMany(mappedBy = "propertyNameAtOwningSide")
mappedBy means its reference is kept at the owning side as a foreign key.
owning: annotated by @ManyToOne @JoinColumninverse: annotated by @OneToMany(mappedBy)
- One to Many: Many-side is always owning side, one side is an inverse side(mapped by).
- One to One: the owning side corresponding to the side to store the foreign key.
- Many to Many: owning side at the conjunction table.
Inverse side
@Entity @Table(name = "LISTER") public class Lister extends User { @OneToOne(mappedBy = "lister") //inverse side private Yard listedYard;Owning side:
@OneToOne @JoinColumn(name = "Lister_ID_FK", referencedColumnName = "USER_PK") protected Lister lister;Unidirectional relationship: two entities, only one entity has a field to keep a foreign key to another entity. So it has only the owning side, which should be defined as the following. The key point is to declare the joined column.
@OneToOne @JoinColumn(name = "ADDRESS_ID_FK", referencedColumnName = "ADDRESS_ID_PK") protected Address address; //owning side keeping FK
Persistence Context
The persistence context is a set of entity instances, which are accessed via an interface, an entity manager. We may manage underlying entities using this interface. The persistence context serves as a first-level cache, buffering the entity instances.
Within the persistence context, the entity instances' lifecycle is managed. An entity instance has four states, i.e. new, managed, removed, or detached.
New state: when an entity is instantiated at the application. It enters the new state.
Managed state: when the instance is persisted, it becomes managed in the persistence context.
Removed state: when the entity instance is set to be removed, after flushing, its counterpart is deleted from the DB.
Detached state: a managed entity instance becomes not managed, and detached from the PC.
The EntityManager API is used to create and remove persistence instances, to find entities by their primary key, and query over entities.
Primary Key
The primary key may uniquely identify an entity(entry), thus the entry can be located and fetched back. A primary key could be simple(one field) or composite(multiple fields).
The simple primary key is defined by an annotation @Id
@Id: Primary key
@GeneratedValue(default strategy = auto-generated)
The composite primary key is defined by an annotation @
EmbeddedId,
meanwhile, a composite primary key is defined by a class, decorated with annotation: @EmbedableLarge Objects
@Lob(large object): designates BLOB(binary large objects) or CLOB(character large objects)
@Basic: designates the fetching type
BLOB: byte[] Byte[]
CLOB: char[] Characeter[]
Inheritance Mapping
There are four types to map inheritance strategies.
Mapped Superclass:
@MappedSuperClass: Table created for each subclass, but not for the superclass; the superclass will be part of the subclass table.
Pros: it is the easiest way to map inheritance;
Cons: cannot query all superclass in one kick, but having to query from subclass tables one by one.
Single table:
Table per class:
Joined table:
Each class in the hierarchy is mapped to an independent database table. Superclass and subclasses are designated as Entities; however, the subclass doesn't hold the fields of the superclass. In the database, they are mapped to their own table.
Dealing Collection of Objects
I think there are two ways to handle a collection of objects.
If an entity contains a collection of a basic type of embedded classes, then using the
If an entity contains a collection of a basic type of embedded classes, then using the
javax.persistence.ElementCollection
( targetClass,
fetch)
annotation. Otherwise from a performance view, it would be better to carry out in a one-to-many relationship.@Entity public class Person { ... @ElementCollection(fetch=EAGER) protected Setnickname = new HashSet(); ... }
Collections may be beyond the List, and Set.
Collections of entity elements and relationships may be represented by java.util.Map collections. A Map consists of a key and a value.
When using Map elements or relationships, the following rules apply.
If the Map value is an entity and part of a many-to-many or one-to-many unidirectional relationship, it will be mapped as a join table in the underlying database. A unidirectional one-to-many relationship that uses a Map may also be mapped using the @JoinColumn annotation.
If the entity is part of a one-to-many/many-to-one bidirectional relationship, it will be mapped in the table of the entity that represents the value of the Map. If generic types are not used, the target entity attribute of the @OneToMany and @ManyToMany annotations must be set to the type of the Map value.
@Embeded (Entity)
@Embedable (Plain Java Class)
@ElementCollection
@Column: designates a database table column.
@Enumrated: designates a persistent attribute that is an enumeration type.
@Transient (a field having no need to be persisted)
Creating Auditing Using Spring JPA
For a large-scale application, it must track when an entity was created and modified and which user did it.
Spring data automatically do that tracking for you
There are two ways.
1. Decorating Entity with predefined Annotations.
@CreatedDate : the entity is first persisted
@Column
private ZonedDateTime createdAt;
@LastModifiedBy: the entity's update was last persisted.
@Column
private User updatedBy;
@CreatedBy: an injected user who created the record
@Column
private User createdBy
@LastModifiedDate: the date last modified.
@Column
private ZonedDateTime lastModified
2. Entity entends from AbstractAuditable Implements Auditable
@Bean SpringSecurityAuditorAware
Collections of entity elements and relationships may be represented by java.util.Map collections. A Map consists of a key and a value.
When using Map elements or relationships, the following rules apply.
If the Map value is an entity and part of a many-to-many or one-to-many unidirectional relationship, it will be mapped as a join table in the underlying database. A unidirectional one-to-many relationship that uses a Map may also be mapped using the @JoinColumn annotation.
If the entity is part of a one-to-many/many-to-one bidirectional relationship, it will be mapped in the table of the entity that represents the value of the Map. If generic types are not used, the target entity attribute of the @OneToMany and @ManyToMany annotations must be set to the type of the Map value.
@Embeded (Entity)
@Embedable (Plain Java Class)
@ElementCollection
@Column: designates a database table column.
@Enumrated: designates a persistent attribute that is an enumeration type.
@Transient (a field having no need to be persisted)
Creating Auditing Using Spring JPA
For a large-scale application, it must track when an entity was created and modified and which user did it.
Spring data automatically do that tracking for you
There are two ways.
1. Decorating Entity with predefined Annotations.
@CreatedDate : the entity is first persisted
@Column
private ZonedDateTime createdAt;
@LastModifiedBy: the entity's update was last persisted.
@Column
private User updatedBy;
@CreatedBy: an injected user who created the record
@Column
private User createdBy
@LastModifiedDate: the date last modified.
@Column
private ZonedDateTime lastModified
2. Entity entends from AbstractAuditable
@Bean SpringSecurityAuditorAware
Managing Transactions
Required
Supports
Mandatory
Never
References:
Subscribe to:
Posts (Atom)
Can Jackson Deserialize Java Time ZonedDateTime
Yes, but must include JSR310. Thus ZonedDateTime can be deserialized directly from JSON response to POJO field. <dependency> <g...
-
Could not extract response: no suitable HttpMessageConverter found for response type [class dk.enettet.evu.core.model.Address] and content ...
-
First time met this hibernate exception. I think this issue should due to one to one relationship. One driver has one car; one car has on...
-
A large object refers to the entity property that is modified by @Lob. It may be persisted in several records. However, in database manage...