Showing posts with label proxy. Show all posts
Showing posts with label proxy. Show all posts

Monday, 9 May 2022

Hibernate Entities in Kotlin

Did a little research what kind of Kotlin classes I should use when creating Entities for the Hibernate framework.

Data classes

Just a short blurp on the requirements that data classes need from [1]:

  • the primary constructor needs to have at least one parameter
  • all primary constructor parameters need to be marked as either val or var
  • data classes cannot be abstract, open, sealed or inner

Hibernate Entities

Just a short blurp on the JPA requirements of entities from [2]

  • The entity class must have a public or protected no-argument constructor.
  • The entity class must be a top-level class.
  • The entity class must not be final. No methods or persistent instance variables of the entity class may be final.
  • The persistent state of an entity is represented by instance variables, which may correspond to JavaBean-style properties. An instance variable must be directly accessed only from within the methods of the entity by the entity instance itself. The state of the entity is available to clients only through the entity’s accessor methods (getter/setter methods) or other business methods.

Conclusion

  • we need to define constructor parameters with var - as they should be mutable
  • we need to specify defaults for every constructor parameter, in order to generate the no-argument constructor
  • Hibernate entities should be "open" in Kotlin (so not final) in order for Hibernate to generate proxies. (this is fixed with the allopen addon in Maven)

So data classes are not a good fit, but a "normal" Kotlin class with just a constructor with annotated vars parameters with default values will work just fine.

References

[1] Kotlin - Data Classes
https://kotlinlang.org/docs/data-classes.html
[2] Hiberante ORM 5.5.9. Final User Guide
https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#entity
Medium.com - Defining JPA/Hibernate Entities in Kotlin
https://medium.com/swlh/defining-jpa-hibernate-entities-in-kotlin-1ff8ee470805

Thursday, 3 February 2022

Hibernate Proxies and the Visitor Pattern

In short, I had a superclass, and two subclasses, each with their own discriminator.

And for each superclass Hibernate returned, it was very important to verify (because business logic) which one was loaded.

But Hibernate creates proxies of the superclass, so the only way to tell is by making sure the business logic is put into the entity itself.

But what if you cannot do that, or do not want to do that, because dependencies and libraries and all that joy.

It can be done by means of the Visitor pattern1.

Performance

It does take a bit of a performance hit, because the Entity needs to be loaded (during the execution of the Visitor pattern) in order to determine the Discriminator.

In our case this wasn't an issue, as the problem occurred in a many-to-one relationships.

In other cases, the query just loads the specific subclass at once.

References

[1] JBoss Community Archive - Proxy Visitor Pattern
https://developer.jboss.org/docs/DOC-13931

Friday, 23 July 2021

Kotlin : the "by" keyword in Interface/Class Delegation

I'm writing it down here, because I looked at it and didn't understand what was going on.

The "by" keyword in Kotlin is used for two things:

  1. Interface/Class delegation1
  2. Delegated properties2

Delegation is a good alternative to inheritance (thought this last statement really requires explanation, or a blogpost on it's own,... or, dare I say, a study on when to use inheritance and when to use delegation and when to use the good old composition).

With the "by" keyword it is possible to use delegation, without adding to the amount of boilerplate that this entails and without having to use inheritance.

Let us give an example using Stubs in testing.

Stubs

So, it seems it's possible to create a simple stub for a test, by using an interface and an implementation and overriding a method (for stubbing). Naturally, the method is not "overridden", but using delegation it is simply implemented in the test, and all other methods are redirected to the stub (which is the delegation class).

So, the syntax1 looks like this:

val/var <propertyname>: <Type> by <expression>

So, for example if you wish to use a delegation (instead of inheritance) in your stub for an OrderService interface.

You create a OrderServiceStub, which makes an empty implementation of all the methods in de OrderService.

And then you can create an anonymous class, indicating which method you wish to change to benefit the test.

It looks like this:

Notice that the anonymous inner class does not inherit from OrderServiceStub (in Kotlin classes are final by default, and we'd like to keep it that way).

The way this can be done without boilerplace in Kotlin is as follows:

So in the second test we're creating an anonymous class, which implements the interface automatically by delegating to the Stub. The only thing we need to change is the method we're interested in.

The next blogpost, we will be diving deeper into Delegated Properties, which looks a little more complicated but is based on the same ideas.

References

[1] Kotlin Language Reference - Delegation
https://kotlinlang.org/docs/delegation.html
[2] Kotlin Language Reference - Delegated properties
https://kotlinlang.org/docs/delegated-properties.html
[3] StackOverflow - What does 'by' keyword do in Kotlin?
https://stackoverflow.com/questions/38250022/what-does-by-keyword-do-in-kotlin

Thursday, 14 February 2019

Nginx - Redirecting to HTTPS

For automatic http->https redirection it is recommended to use Apache or Nginx in front of Payara to do the redirection, see [1].

I decided on using nginx for this2 3 4.

Before nginx, it looks like this:

$ curl -s -D - http://www.mrbear.org -o /dev/null
HTTP/1.1 200 OK
Server: Payara Server  5.184 #badassfish
X-Powered-By: Servlet/4.0 JSP/2.3 (Payara Server  5.184 #badassfish Java/Oracle Corporation/1.8)
Content-Type: text/html;charset=ISO-8859-1
Transfer-Encoding: chunked
X-Frame-Options: SAMEORIGIN

Configuration is found in /etc/nginx/nginx.conf.

I changed it into something very simple:

server {
      listen      80 default;
      access_log off;
      error_log off;
      return      301 https://$server_name$request_uri;
}

Double checking:

# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Enabling automatic start and also starting nginx.

# systemctl enable nginx
# systemctl start nginx

So, let's try seeing what the webserver now responds with:

$ curl -s -D - http://www.mrbear.org -o /dev/null
HTTP/1.1 301 Moved Permanently
Server: nginx/1.12.2
Date: Mon, 28 Jan 2019 16:28:59 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: https://www.mrbear.org/

$ curl -s -D - http://www.mrbear.org/this/is/some/url.jsf -o /dev/null
HTTP/1.1 301 Moved Permanently
Server: nginx/1.12.2
Date: Mon, 28 Jan 2019 16:31:06 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: https://www.mrbear.org/this/is/some/url.jsf

References

[1] Payara - How to Secure Payara Server with Apache
https://blog.payara.fish/how-to-secure-payara-server-with-apache
[2] How To Nginx Redirect All HTTP Request To HTTPS Rewrite 301 Rules
https://www.cyberciti.biz/faq/linux-unix-nginx-redirect-all-http-to-https/
[3] How to do an Nginx redirect
https://bjornjohansen.no/nginx-redirect
[4] Creating NGINX Rewrite Rules
https://www.nginx.com/blog/creating-nginx-rewrite-rules/
DigitalOcean - How To Install Nginx on CentOS 7
https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-centos-7