Category Archives: Java

JPA inheritance performance improvement

This article is about improving JPA's performance when working with large/thick hierarchies.

Let's suppose that for some reason you have a similar (or larger) hierarchy to one I encountered in one of my projects:
- InheritanceType.JOINED also using DiscriminatorColumn
- 4 levels hierarchy (including root entity)
- 24 entities actually making the hierarchy
- 7 properties as an average for each entity (excluding @Id)
- other entities are referenced by those actually making the hierarchy
- using hibernate JPA 2.1 api (though this might not be important)

When retrieving an entity I face the situation of about 70 tables being joined (24 from the hierarchy and 46 other referenced entities) and the performance is pathetic. Of course I have the appropriate indexes painfully chosen by testing every query with EXPLAIN ANALYZE.

Part of the problem is that I also have a large table for the hierarchy's root (26 million of rows). The other part is the way JPA is working: I mean when I try to get the root entities filtered by few discriminator types then JPA creates a 70 tables SELECT instead of using only the tables making sense for those specific discriminators. 

Let's name RootEntity the root entity of my JPA hierarchy. Let's also suppose I have Level4Entity (with 4a as discriminator) which inherits from Level3Entity which inherits from Level2Entity which inherits RootEntity. When querying for RootEntity using 4a and 4b discriminator types as criteria then JPA is using the same query as when querying for RootEntity's entire hierarchy (70 tables as a total). Should JPA only use the tables required by Level4Entity's specific sub-hierarchy (e.g. 12 tables: 4 for hierarchy and other 8 referenced) then the performance would be much better. Even when simply retrieving a RootEntity entity by its @Id the timing is 12 seconds!

The client cares only for the performance (while using same hardware) asks: can you do better? Well, let's now just imagine the totally crazy idea of using InheritanceType.SINGLE_TABLE instead of InheritanceType.JOINED. For me this would mean an 177 columns table for RootEntity's and liquibase scripts in order to copy the columns and data from previous tables to the RootEntity's table, refactor FKs and indexes. But would this effort worth? Well, if your database supports materialized views you could test this approach before changing your code and database. You could simply create a materialized view based on the actual 70 tables SELECT generated by JPA then you could test the retrieving of one row by pk (somehow equivalent to the previously retrieving by @Id which took 12 seconds). If you really want the best comparison than you should include in the materialized view only the tables used directly by the hierarchy (24 tables) which is not so straight forward but still easy to do. For me this approach allowed for a 450 ms when retrieving an entity instead of 12 s as before - quite a huge difference. 

So yes, changing the hierarchy to InheritanceType.SINGLE_TABLE and using a many-columns table with many possible null columns was by far faster then using InheritanceType.JOINED approach. And not only the retrieve was faster but also the INSERT (I don't remember exactly by how much but at least 5 times faster). 

So, what are the pro and cons of the approach?

PROS: 
- speed: both for query and insert
- sql simplicity: I find easier to read a many columns SELECT instead of many JOIN SELECT

CONS: 
- database structure: you'll have 1 many columns table versus many tables
- database consistency: columns which were NOT NULL in their dedicated table should now accept NULL in order to account for the situation when their row might not exists for a specific sub-hierarchy

Observation: with Oracle table partitioning on the join columns of the hierarchy I guess (but never tested) you should gain same performance benefit while still using InheritanceType.JOINED

Spring security with kerberos

What is a keytab, and how do I use one?
Introduction to Kerberos for Managers
Crash Course to Kerberos
Appendix D. Troubleshooting
JAAS authentication with Kerberos
http://www.roguelynn.com/words/explain-like-im-5-kerberos/
KDC = Kerberos Key Distribution Center
TGT = Ticket Granting Ticket
TGS = Ticket Granting Server

For the configuration below (just a copy from spring security reference):
<sec:authentication-manager alias="authenticationManager">
	<sec:authentication-provider ref="kerberosAuthenticationProvider"/>
</sec:authentication-manager>

<bean id="kerberosAuthenticationProvider"
	class="org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider">
	<property name="kerberosClient">
		<bean class="org.springframework.security.kerberos.authentication.sun.SunJaasKerberosClient">
			<property name="debug" value="true"/>
		</bean>
	</property>
	<property name="userDetailsService" ref="dummyUserDetailsService"/>
</bean>

<bean
	class="org.springframework.security.kerberos.authentication.sun.GlobalSunJaasKerberosConfig">
	<property name="debug" value="true" />
	<property name="krbConfLocation" value="/path/to/krb5.ini"/>
</bean>

<bean id="dummyUserDetailsService"
	class="org.springframework.security.kerberos.docs.DummyUserDetailsService" />
The file /path/to/krb5.ini could be an exact copy of /etc/krb5.conf from the KDC machine. You'll have to make sure the host names used in krb5.ini's default_realm are accessible for the application.

Spring security

HTML translated to java config
see also Java Configuration
see also http://www.springframework.org/schema/security/spring-security.xsd

<http security="none" pattern="/resources/**"/>
<http pattern="/api1/**" create-session="stateless">
	<intercept-url pattern="/**" access="authenticated"/>
	<http-basic />
</http>
<http pattern="/api2/**" create-session="never">
	<intercept-url pattern="/api2/api21/**" access="hasRole('ROLE_ADMIN')"/>
	<intercept-url pattern="/api2/**" access="hasRole('ROLE_USER')"/>
	<http-basic />
</http>
<http pattern="/api3/**">
	<intercept-url pattern="/api3/api31/**" access="hasRole('ROLE_ADMIN')"/>
	<intercept-url pattern="/api3/api32/**" access="hasRole('ROLE_USER')"/>
	<intercept-url pattern="/**" access="authenticated"/>
	<http-basic />
</http>
<http>
	<intercept-url pattern="/logout" access="permitAll"/>
	<intercept-url pattern="/login" access="permitAll"/>
	<intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
	...
	<form-login login-page="/services/session" login-processing-url="/login"
				password-parameter="password" username-parameter="username"
				logout-success-url="/services/session" ... />
	<http-basic />
	<logout invalidate-session="true"/>
</http>
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
    @Autowired
    private AuthenticationManager am;

    /**
     * @param auth
     * @throws Exception
     */
    @Autowired
    public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
        auth.parentAuthenticationManager(this.am);
    }
}
@Configuration
@Order(1)
public class Api1Authentication extends WebSecurityConfigurerAdapter {
	@Override
	protected void configure(final HttpSecurity httpSecurity) throws Exception {
		httpSecurity.antMatcher("/api1/**")
					.authorizeRequests().anyRequest().authenticated()
					.and()
					.httpBasic()
					.and()
					.sessionManagement()
					.sessionCreationPolicy(SessionCreationPolicy.STATELESS);    
	}
}
@Configuration
@Order(2)
public class Api2Authentication extends WebSecurityConfigurerAdapter {
	@Override
	protected void configure(final HttpSecurity httpSecurity) throws Exception {
		httpSecurity.antMatcher("/api2/**")
					.authorizeRequests()
					.antMatchers("/api2/api21/**").hasRole("ADMIN")
					.antMatchers("/api2/**").hasRole("USER")
					.and()
					.httpBasic()
					.and()
					.sessionManagement()
					.sessionCreationPolicy(SessionCreationPolicy.NEVER);    
	}
}
@Configuration
@Order(3)
public class Api3Authentication extends WebSecurityConfigurerAdapter {
	@Override
	protected void configure(final HttpSecurity httpSecurity) throws Exception {
		httpSecurity.antMatcher("/api3/**")
					.authorizeRequests()
					.antMatchers("/api3/api31/**").hasRole("ADMIN")
					.antMatchers("/api3/api32/**").hasRole("USER")
					.anyRequest().authenticated()
					.and()
					.httpBasic();    
	}
}
@Configuration
public class OtherAuthentication extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(final WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/**");
    }

    @Override
    protected void configure(final HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                    .formLogin()
                    .loginPage("/services/session")
                    .loginProcessingUrl("/login")
                    .usernameParameter("username")
                    .passwordParameter("password")
                    .defaultSuccessUrl("/services/session")
                    .failureHandler(new DdcAuthenticationFailureHandler())
                    .permitAll()
                    .and()
                    .httpBasic()
                    .and()
                    .logout()
                    .logoutSuccessUrl("/services/session")
                    .invalidateHttpSession(true);
    }
}
Q1: why should I use antMatcher("/api2/**") while anyway the subsequent antMatchers(...) cover the entiy /api2/** paths?
A1: because antMatcher has the purpose of mapping the  security configuration while antMatchers accompanies authorizeRequests() in order to specify request access conditions (e.g. roles). antMatchers could accompany also requiresChannel() in order to specify the protocol (http, https, any). If not using antMatcher that would be like  security configuration wouldn't use the pattern attribute (equivalent to using /**).

OtherAuthentication allows the use of form and basic authentication (using the order of declaration). So when not authenticated user access /services/session (using no Authorization header) he would get back a response (e.g. json containing a CSRF token :D). When the user tries to POST /services/session using the received CSRF token he will then be authenticated using basic authentication when he use Authorization header or form authentication otherwise (suppose he uses a valid token otherwise spring will consider a CSRF attack). When one tries to access /some-not-resources-and-not-api123-path with the header Authorization filled with a valid user/password than the basic authentication will be enforced and the user will get the result; if user/password is wrong he will get http code 401. 

/api2/** has SessionCreationPolicy.NEVER which means it won't create a session (when using basic authentication) but it might use one when the user already created one like when authenticated with form-authentication.

/api1/** has SessionCreationPolicy.STATELESS which means it will not create a session but also it will invalidate it if found so it does not live well with OtherAuthentication which creates (in order to use) a session. This means that after a form authentication the user will be disconnected after trying to access /api1/**.

JPA performance

http://java-persistence-performance.blogspot.ro/2011/06/how-to-improve-jpa-performance-by-1825.html#
http://spitballer.blogspot.ro/2010/04/jpa-persisting-vs-merging-entites.html

Use byte code weaving
EclipseLink implements LAZY for OneToOne and ManyToOne relationships using byte code weaving

Pagination
Use setFirstResult, setMaxResults of javax.persistence.Query.

Caching
See https://docs.oracle.com/javaee/7/tutorial/persistence-cache001.htm#GKJIO.
See <shared-cache-mode> in persistence.xml or javax.persistence.sharedCache.mode property when creating the EntityManagerFactory.
See javax.persistence.Cacheable used to annotate an entity.

JDBC batching (insert/update only)
See http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/#batch.
hibernate.jdbc.batch_size: a non-zero value enables use of JDBC2 batch updates by Hibernate. e.g. recommended values between 5 and 30

JDBC fetch size (retrieve only)
hibernate.jdbc.fetch_size: a non-zero value determines the JDBC fetch size (calls Statement.setFetchSize())
Statement.setFetchSize: gives the JDBC driver a hint as to the number of rows that should be fetched from the database when more rows are needed for ResultSet objects genrated by this Statement. If the value specified is zero, then the hint is ignored. The default value is zero.
In my opinion the best explanation is here: https://docs.oracle.com/cd/E11882_01/java.112/e16548/resltset.htm#JJDBC28621
Excerpt: Standard JDBC also enables you to specify the number of rows fetched with each database round-trip for a query, and this number is referred to as the fetch size.

Hibernate batch size (@BatchSize)
http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/#performance-fetching
@BatchSize specifies a "batch size" for fetching instances of this class by identifier. Not yet loaded instances are loaded batch-size at a time (default 1).

Hibernate fetching strategies (@Fetch)
http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/#performance-fetching
http://www.mkyong.com/hibernate/hibernate-fetching-strategies-examples/
Fetching strategies: join fetching, select fetching, subselect fetching, batch fetching.

other
http://www.jroller.com/eyallupu/entry/solving_the_simultaneously_fetch_multiple1

hibernate.default_batch_fetch_size
http://stackoverflow.com/questions/21162172/default-batch-fetch-size-recommended-values
http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch03.html
see also hibernate.batch_fetch_style at http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/#performance-fetching
https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/main/java/org/hibernate/loader/BatchFetchStyle.java specifies LEGACY as the default for hibernate.batch_fetch_style

JAXB 2.2.10

see also http://docs.oracle.com/javaee/5/tutorial/doc/bnbbf.html
see also https://jaxb.java.net/tutorial/index.html
see also https://jaxb.java.net/guide/index.html - Unofficial JAXB Guide
see also How to get simple and better typed binding in https://metro.java.net/guide/ch03.html

globalBindings
<jxb:globalBindings
     fixedAttributeAsConstantProperty="false"
     collectionType="java.util.Vector"
     typesafeEnumBase="xsd:string"
     choiceContentProperty="false"
     typesafeEnumMemberName="generateError"
     enableFailFastCheck="false"   
     generateIsSetMethod="false"
     underscoreBinding="asCharInWord"/>
fixedAttributeAsConstantProperty
fixed attributes will be generated as a java constant.
<xs:attribute name="country" type="xs:NMTOKEN" fixed="US"/>
@XmlSchemaType(name = "NMTOKEN")
public final static String COUNTRY = "US";
collectionType
Specifies the base type used for collections.
<xs:element name="item" minOccurs="1" maxOccurs="unbounded">
@XmlElement(required = true)
protected List<Items.Item> item = new Vector<Items.Item>();
typesafeEnumBase
typesafeEnumBase = a list of QNames, each of which must resolve to a simple type definition
Specifies that all simple type definitions deriving directly or indirectly from e.g. xsd:string and having enumeration facets should be bound by default to a typesafe enum.
<xs:simpleType name="USState">
	<xs:restriction base="xs:string">
		<xs:enumeration value="AK"/>
		<xs:enumeration value="AL"/>
		<xs:enumeration value="AR"/>
		<xs:enumeration value="CA"/>
		<xs:enumeration value="MA"/>
		<!-- and so on ... -->
	</xs:restriction>
</xs:simpleType>
choiceContentProperty
The default value is false. choiceContentProperty is not relevant when the bindingStyle is elementBinding (see below).
<xs:complexType name="fileUploadRequest">
	<xs:choice>
		<xs:element name="path" type="xs:string"/>
		<xs:element name="file" type="xs:base64Binary"/>
	</xs:choice>
</xs:complexType>
Xjc with choiceContentProperty="false":
public class FileUploadRequest {
    protected String path;
    protected byte[] file;
Xjc with choiceContentProperty="true":
@XmlElements({
    @XmlElement(name = "path", type = String.class),
    @XmlElement(name = "file", type = byte[].class)
})
protected Object pathOrFile;
typesafeEnumMemberName
typesafeEnumMemberName = "generateName" | "generateError"
generateError specifies that the code generator generates an error when it cannot map an enumeration to a Java enum type.
<xs:simpleType name="USState">
	<xs:restriction base="xs:string">
		<xs:enumeration value="CA"/>
		<xs:enumeration value="MA"/>
		<xs:enumeration value="1MA"/> -> 1MA is an invalid java name
		<!-- and so on ... -->
	</xs:restriction>
</xs:simpleType>
[ERROR] Cannot generate a constant name from the enumeration value "1MA". Use <jaxb:typesafeEnumMember name="..."/> to specify one.
generateName specifies that member names will be generated following the pattern VALUE_N. N starts off at one, and is incremented for each member of the enumeration.
    @XmlEnumValue("1MA")
    VALUE_6("1MA");
    private final String value;
enableFailFastCheck
Type constraint checking is performed when setting a property.
item.setQuantity( new BigInteger( "-5" ) );// must be a positive number here
If @enableFailFastCheck was "true" and the optional FailFast validation method was supported by an implementation, a TypeConstraintException would be thrown here. Note that the JAXB implementation does not support the FailFast feature.

generateIsSetMethod
First see FileUploadRequest schema declaration above.
Causes two additional property methods, isSetPath and isSetFile, to be generated. These methods enable a client application to distinguish between schema default values and values occurring explicitly within an instance document. Some good folks claim unsetPath and unsetFile should be generated too but it didn't happened for me (with or without a default attribute set on path element).

underscoreBinding
Consider this element:
<xs:element name="sOmE_PROPerty" type="xs:string"/>
Jxc generation result when asWordSeparator (default value):
@XmlElement(name = "sOmE_PROPerty")     -> it's an invisible underscore between sOmE and PROPerty
protected String sOmEPROPerty;
Jxc generation result when asCharInWord:
protected String sOmE_PROPerty;         -> it's an invisible underscore between sOmE and PROPerty

Spring Data REST

The core functionality of Spring Data REST is to export resources for Spring Data repositories.
Spring Data REST exposes sub-resources of every item resource for each of the associations the item resource has. By default, Spring Data REST uses HAL (hypertext application language) to render responses.

RepositoryRestMvcConfiguration - the @Configuration for Spring Data REST
RepositoryRestConfigurerAdapter - used to customize the configuration

By default, Spring Data REST serves up REST resources at the root URI, "/". Register a @Bean which extends RepositoryRestConfigurerAdapter and overwrite configureRepositoryRestConfiguration in order to change it. With spring boot use spring.data.rest.basePath=/new-base-path-for-spring-data-rest in application.properties.
http://ip:port/base-path-for-spring-data-rest returns a JSON with the first level of resources provided with Spring Data REST.

@RepositoryRestResource - used on a Repository interface to customize the path and name of the resource
@RestResource - used on a method to customize the path and name of the exported resource; use exported = false in order not to export the resource

Annotation org.springframework.data.rest.core.config.Projection used to define altered views for entities (e.g.: not showing the password for user).
URI would look like: http://localhost:8080/persons/1?projection=noPassword
@Projection can be used with SpEL expression to create new properties.
An excerpt is a projection that is applied to a resource collection automatically, e.g.:
@RepositoryRestResource(excerptProjection = NoPassword.class)
interface PersonRepository extends CrudRepository {}

Validation is achived using a registered org.springframework.validation.Validator instance:
a. beforeCreatePersonValidator -> prefix the bean name with the Data REST event name
b. assigning Validators manually -> override RepositoryRestMvcConfiguration.configureValidatingRepositoryEventListener and add the validators

Events: BeforeCreateEvent, AfterCreateEvent, BeforeSaveEvent, AfterSaveEvent, BeforeLinkSaveEvent, AfterLinkSaveEvent, BeforeDeleteEvent, AfterDeleteEvent. Writing an ApplicationListener:
a. extend AbstractRepositoryEventListener (onBeforeSave, etc) -> makes no distinction based on the type of the entity
b. write an annotated handler -> @RepositoryEventHandler on class and @HandleBeforeSave on method (first parameter determines the domain type whose events you’re interested)

Creating links from Spring MVC controllers to Spring Data REST resources is possible with injectable RepositoryEntityLinks (equivalent to EntityLinks from Spring HATEOAS): entityLinks.linkToCollectionResource(Person.class).

ALPS (Application-Level Profile Semantics) is a data format for defining simple descriptions of application-level semantics.
ALPS (application/alps+json or application/schema+json) -> used for metadata provided by a Spring Data REST-based application.
http://ip:port/base-path-for-spring-data-rest/profile -> metadata location
ALPS list first entity's attributes (+ projections) then operations.

Spring security works fine with Spring Data REST; just use @PreAuthorize as usual.

The developer of the HAL spec has a useful application: the HAL Browser.

Write a custom handler (overriding Spring Data REST response handlers) for a specific resource using @RepositoryRestController (instead of @RestController). There's a custom HandlerMapping instance that responds only to the RepositoryRestController which is considered before the one for @Controller or @RestController.

Use ResourceProcessor interface in order to provide links to other resources from a particular entity. You declare spring beans implementing ResourceProcessor for a specific entity.
If you register your own ConversionService in the ApplicationContext and register your own Converter, then you can return a Resource implementation of your choosing.

Maven dependency
<dependency>
  org.springframework.data
  spring-data-rest-webmvc
  2.4.2.RELEASE
</dependency>

Spring HATEOAS

HATEOAS means Hypermedia As The Engine Of Application State

ResourceSupport - support class for building DTOs with links

ControllerLinkBuilder - allows to create links by pointing to controller classes (Spring MVC controllers or JAX-RS resource classes)
With ControllerLinkBuilder you depend on controller classes in order to create links.

@EnableEntityLinks - inspects Spring MVC controllers and JAX-RS resource for @ExposesResourceFor(model class) and allows injecting of EntityLinks
With EnableEntityLinks you depend on model/business classes in order to create links; I think it's better instead of ControllerLinkBuilder.

Apache CXF 3.0.3

Scenario 1
All jax-rs annotation are applied on interface.
No jax-rs annotation are applied on class.

@POST
@Consumes({ APPLICATION_XML })
method1(InputStream istream)

@POST
@Consumes({ APPLICATION_FORM_URLENCODED })
method2a(@FormParam("") final Pojo2 p2)        -> won't detect it as a resource method

@POST
@Consumes({ APPLICATION_FORM_URLENCODED })
@Produces({ APPLICATION_XML })
@Path("/method2b")
method2b(@FormParam("") final Pojo2 p2)

Scenario 2
All jax-rs annotation are applied on interface as specified above in scenario 1.
The class only have the jax-rs annotations specified below.

@Override
method2a(@FormParam("") final Pojo2 p2)        -> won't detect it as a resource method
@Override
method2b(@FormParam("") final Pojo2 p2)        -> won't detect it as a resource method

Scenario 3
All jax-rs annotation are applied on interface as specified above in scenario 1.
The class only have the jax-rs annotations specified below.

@Override
method1(InputStream istream)

@Override
@POST
@Consumes({ APPLICATION_FORM_URLENCODED })
method2a(@FormParam("") final Pojo2 p2)

@Override
@POST
@Consumes({ APPLICATION_FORM_URLENCODED })
@Produces({ APPLICATION_XML })
@Path("/method2b")
method2b(@FormParam("") final Pojo2 p2)

Everything is working as expected.

Scenario 4
All jax-rs annotation are applied on interface as specified above in scenario 1.
The class only have the jax-rs annotations specified below.

@Override
method1(InputStream istream)

@Override
@POST
method2a(final Pojo2 p2)

@Override
method2b(final Pojo2 p2)

method2a is mapped to mediaType="*/*" (though the interface is specifying application/x-www-form-urlencoded).
method2a won't accept application/x-www-form-urlencoded payload (seems to ignore @FormParam annotation from interface).
Everything else is working as expected.

Scenario 5
All jax-rs annotation are applied on interface as specified above in scenario 1.
The class only have the jax-rs annotations specified below.

@Override
method1(InputStream istream)

@Override
@POST
@Consumes({ APPLICATION_FORM_URLENCODED })
method2a(final Pojo2 p2)

@Override
method2b(final Pojo2 p2)

method2a is mapped to mediaType="application/x-www-form-urlencoded" (as the interface is specifying).
method2a won't accept application/x-www-form-urlencoded payload (seems to ignore @FormParam annotation from interface).
Everything else is working as expected.

Scenario 6
All jax-rs annotation are applied on interface as specified above in scenario 1.
The class only have the jax-rs annotations specified below.

@Override
method1(InputStream istream)

@Override
@POST
method2a(@FormParam("") final Pojo2 p2)

@Override
method2b(final Pojo2 p2)

Everything is working as expected.

CXF JAX-RS configuration: http://cxf.apache.org/docs/jaxrs-services-configuration.html

CXF specific
QueryParam("") - CXF extension supporting the injection of all the parameters of specific JAX-RS type (example, QueryParam("") MyBean).
StreamingResponse - use it instead of StreamingOutput in order to auto-serialize T

JAX-RS with Jersey

Terms
resource method designator - annotation such as @GET, @PUT, @POST, @DELETE
sub-resource methods - methods annotated with @Path and also with resource method designators such as @GET or @POST
sub-resource locators - methods annotated with @Path but not with resource method designators such as @GET or @POST

Tips & Tricks
Jersey gives you an option to register so called model processor providers (org.glassfish.jersey.server.model.ModelProcessor). These providers are able to modify or enhance the application resource model during application deployment.

Use @InjectLink on an entity (returned by server) field in order to inject it with a link (intead of using a link header).

Do not use ApacheConnectorProvider nor GrizzlyConnectorProvider neither JettyConnectorProvider connector implementations with Jersey Multipart features. See Header modification issue warning for more details.

javax.activation.MimetypesFileTypeMap - utility for getting the MIME type of a file

@Produces({"application/xml; qs=0.9", "application/json"})
If client accepts both "application/xml" and "application/json" (equally), then a server always sends "application/json", since "application/xml" has a lower quality factor.

HttpHeaders, Request, UriInfo, SecurityContext can be injected into constructor or class fields of a singleton (using the @Context annotation).
For these objects the runtime will inject proxies which are able to simultaneously server more request.

The @FormParam annotation is special and may only be utilized on resource and sub-resource methods. This is because it extracts information from a request entity.

By default, the transport layer in Jersey is provided by HttpUrlConnection. This transport is implemented in Jersey via HttpUrlConnectorProvider that implements Jersey-specific Connector SPI. HttpUrlConnection by default restricts the use of some headers. In order to permit all headers to be sent the system property sun.net.http.allowRestrictedHeaders must be set to "true".

Sub-resource locator return types
@Path("/")
public ItemContentResource getItemContentResource() {
	// instance
	return new ItemContentResource();
}
@Path("kid1")
public Class getMySubResource1() {
	// Class
	return MySubResource1.class;
}
@Path("kid2")
public Resource getMySubResource() {
	// Resource (programmatic resource model return type)
	return Resource.from(MySubResource2.class);
}
@Path("kid5")
public MySubResource5 getMySubResource(@QueryParam("impl") String impl) {
	// Object (the way to support polymorphism)
	// @QueryParam("impl") won't be available into sub-sesource
	if (impl.equals("a")) {
		return new MySubResource5a(impl);
	} else {
		return new MySubResource5b(impl);
	}
}

Architecture (the usual usage)
invocating a jax-rs service
ClientBuilder builds Client (dealing with registration of providers, features, filter and interceptors).
Client builds WebTarget (dealing with the URI construction including query and matrix parameters, template values).
WebTarget builds Invocation.Builder (dealing with any except URI construction; deals with headers and cookies, filter-accesible properties).
Invocation.Builder builds Invocation/AsyncInvoker (dealing with the "actual call" and getting the result).
Invocation.Builder can behave also as SyncInvoker in order to do the "actual call".

javax.ws.rs.core.Response created by server
Response creates a ResponseBuilder while also being able to set the http status.
ResponseBuilder sets headers (status, link, lastModified, entity tag, location, etc), cookies, entity (+annotations).
ResponseBuilder then builds the Response.

javax.ws.rs.core.Response used by client
Response is obtained as a result of the "actual call" facilitated by Invocation.Builder.
Response provides headers, cookies and entity access (Response.readEntity(Class entityType, Annotation[] annotations)).
For reading the entity a MessageBodyReader in used based also on annotations provided to Response.readEntity().

Chunked Output
In Jersey you can use ChunkedOutput to send response to a client in chunks. 
This can be achived by returning ChunkedOutput from a resource method - this makes the method automatically asynchronous.
Then one writes T for the client using ChunkedOutput. After sending some T one should close the ChunkedOutput.

Client side one uses Response.readEntity in order to get a ChunkedInput from which reads T while not null.

Server-Sent Events
This is the server side support for services which can be consumed from java script with EventSource.
The resource method should return org.glassfish.jersey.media.sse.EventOutput which is a ChunkedOutput - this makes the method automatically asynchronous. Then one uses EventOutput in order to write OutboundEvent which is a wrapper for the actual entity one wants to send. Finally one would close the EventOutput in order to end the communication.

Client side one gets a EventInput instance from where reads InboundEvent which is a wrapper for the actual entity sent by server. The connection is closed when null EventInput is received or InboundEvent.isClosed() returns true.
instead of getting an EventInput instance one could use EventSource then register an EventListener in order to receive InboundEvent.

security
Security information of a request is available by injecting a JAX-RS SecurityContext instance using @Context annotation.
You can define the access to resources using annotations from package javax.annotation.security defined by JSR-250 (PermitAll, RolesAllowed).

bean validation support
Jersey does not support, and doesn't validate, constraints placed on constructors and Bean Validation groups (only Default group is supported at the moment). Constraint annotations are allowed in resource method parameters, fields and property getters as well as resource classes, entity parameters and resource methods (return values). E.g. validation on resource method parameters:
@NotNull @FormParam("lastName") String lastName, @Email @FormParam("email") String email, @Valid User user.
The @Email annotation is defined as:
@Constraint(validatedBy = EmailValidator.class)
public @interface Email { ...
The constraint class is defined as:
public class EmailValidator implements ConstraintValidator { ...

Entity Data Filtering
Entity filtering is achived with:
- custom annotations (server and client side support)
- role-based Entity Filtering using (javax.annotation.security) annotations (server and client side support)
- dynamic and configurable query parameters
With custom annotations one uses @EntityFiltering meta-annotation to creates a custom annotation e.g. @UserDetailedView.
Then creates a response e.g.:
Response.ok().entity(new User(), isDetailed ? new Annotation[]{UserDetailedView.Factory.get()} : new Annotation[0]).build();
or 
simply annotates with @ProjectDetailedView the resource method.
Then the client shall receive an User entity populated only for the fields annotated with @UserDetailedView or not annotated at all with @EntityFiltering.
With role-based Entity Filtering using (javax.annotation.security) annotations one uses javax.annotation.security annotations same way as he would with custom annotations entity-filtering. Instances of security annotations can be created using SecurityAnnotations factory class that is part of the Jersey Entity Filtering API.
Entity Filtering based on dynamic and configurable query parameters allows one to specify the select query parameter in order to filter the entity's fields e.g. http://example.com/user/51234?select=name,surname,country.name -> here only name, surname, country.name fields from User entity shall be populated.

MVC Templates
Use @Template(templateName) on a resource method in order to define a template (jep, freemarker, mustache) processing the entity returned. 
Jersey will assign the entity instance to an attribute named model which can be user with e.g. ${model} in jsp or freemarker.
One could use @ErrorTemplate the same way where Bean Validation errors will be accessible with the attribute name error.

Configuration
jersey specific: org.glassfish.jersey.client.ClientConfig implements javax.ws.rs.core.Configurable, ...
jersey specific: org.glassfish.jersey.client.ResourceConfig implements javax.ws.rs.core.Configurable, ...
ClientConfig and ResourceConfig both use javax.ws.rs.core.Configurable's ergonomic methods in order to construct javax.ws.rs.core.Configuration.
While constructing javax.ws.rs.core.Configuration also ResourceConfig constructs javax.ws.rs.core.Application (main objective by the way).
ClientConfig aim is the construct of a javax.ws.rs.core.Configuration which further would be used by 
javax.ws.rs.client.ClientBuilder.newClient(Configuration configuration) to construct javax.ws.rs.client.Client.

Filters can be used when you want to modify any request or response parameters like headers.

Interceptors share a common API for the server and the client side. Whereas filters are primarily intended to manipulate request and response parameters like HTTP headers, URIs and/or HTTP methods, interceptors are intended to manipulate entities, via manipulating entity input/output streams.

@MapKey vs @MapKeyColumn

// @MapKey refers the field/property (unique one) in the Entity witch is the value of a Map field/property
// @MapKeyColumn refers the column in an @ElementCollection

@Entity
public class Person6 {
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "person6")
    @MapKey(name = "address") // is the Address6's address property
    public Map<String, Address6> getAddress6Map() {
        return address6Map;
    }
...

@Entity
public class Address6 {
    private Integer id;
    private String address;
    private Person6 person6;
...

ESB

ESB
- match and route (filter node for IBM)
- convert (protocols)
- format data
- orchestration (e.g. from some web services, dbs, files, etc collect partial data and create a new web services)
- event delivering

ESB = Enterprise service bus
contains the integration logic

IBM Integration BUS = IBM's ESB implementation