Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/honoluluhenk/id-class
Typesafe value-object for use in persistence and/or (Jax-)DTOs
https://github.com/honoluluhenk/id-class
hibernate jackson java jpa quarkus spring
Last synced: about 1 month ago
JSON representation
Typesafe value-object for use in persistence and/or (Jax-)DTOs
- Host: GitHub
- URL: https://github.com/honoluluhenk/id-class
- Owner: HonoluluHenk
- License: lgpl-3.0
- Created: 2021-03-08T20:04:05.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2022-08-19T23:08:48.000Z (about 2 years ago)
- Last Synced: 2024-10-14T04:02:03.990Z (about 1 month ago)
- Topics: hibernate, jackson, java, jpa, quarkus, spring
- Language: Java
- Homepage:
- Size: 137 KB
- Stars: 2
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
## id-class
[![Maven Central](https://img.shields.io/maven-central/v/com.github.honoluluhenk.id-class/id-class)](https://search.maven.org/artifact/com.github.honoluluhenk.id-class/id-class)
[![Issues](https://img.shields.io/github/issues/HonoluluHenk/id-class)](https://github.com/HonoluluHenk/id-class/issues)
[![GitHub contributors](https://img.shields.io/github/contributors/HonoluluHenk/id-class)](https://github.com/HonoluluHenk/id-class/graphs/contributors)
[![GitHub stars](https://img.shields.io/github/stars/HonoluluHenk/id-class?style=social)](https://github.com/HonoluluHenk/id-class)
[![GitHub forks](https://img.shields.io/github/forks/HonoluluHenk/id-class?style=social)](https://github.com/HonoluluHenk/id-class/network/members)Helps binding IDs of objects/entities to their type and thus prevents using IDs for the wrong object/entity - and
implicitly documents the entity-type associated to the ID.## Motivation
Have you ever mixed up your variables containing UUID/String/Long/... IDs in JPA/Hibernate/JAX-RS or other frameworks?
Like maybe so?
```java
import java.util.UUID;class SomeEntity {
@Id
public UUID id = UUID.randomUUID();
}class OtherEntity {
@Id
public UUID id;
}class Foo {
void doStuff(OtherEntity otherEntity) {
// id gets "transformed" to id of wrong entity:
UUID id = otherEntity.getId();// and now you e.g. try to load SomeEntity
// with the id of OtherEntity but did not find anything:
SomeEntity someEntity = entityManager.find(SomeEntity.class, id);
}
}
```*id-class* to the rescue: now you can have typed IDs bound to the entity-type:
```java
import com.github.honoluluhenk.idclass.ID;public class SomeEntity {
@Id
public ID id = ID.randomUUID(SomeEntity.class); // directly support ID generation
}class OtherEntity {
@Id
public UUID id;
}class Foo {
void doStuff(OtherEntity otherEntity) {
// compiler error: ID is not compatible with ID
ID id = otherEntity.getId();// direct integration into hibernate!
SomeEntity someEntity = entityManager.find(SomeEntity.class, id);
}
}```
(this example is using UUIDs, but there are more options and it's customizable)
You will also find modules to integrate this nicely into
* [JAX-RS with Jackson](https://github.com/FasterXML/jackson)
* [JPA with Hibernate](https://hibernate.org/)## Installation/Basic Usage
### Just the basic ID class
Install using maven:
```xml
com.github.honoluluhenk.id-class
id-class
${id-class-parent.version}
```
Basic usage:
The ID class mainly consists of various factory methods:
```java
class Foo {
private ID id = ID.randomUUID();
private ID id = ID.of(UUID.fromString("af897f93-9067-48a3-96aa-974511a5c3c4"));
private ID id = ID.of("cb310f0f-596e-48f5-b6b6-25301d589fe5");
//... and more
}
```ID is immutable, comes with hashCode()/equals(), a nice toString() and implements Serializable.
See javadoc comments or [ID.java source](id-class/src/main/java/com/github/honoluluhenk/idclass/ID.java).
Most of its value actually comes from using it in one of the integrations, see below.
### Jackson Integration
Install using maven (also pulls in the basic ID class):
```xml
com.github.honoluluhenk.id-class
id-class-jackson-integration
${id-class-parent.version}
```
**You need to declare dependencies to jackson yourself (so you don't end up in dependency hell)!**
Jackson integration contains two parts:
* a [ParamConverter](https://docs.oracle.com/javaee/7/api/javax/ws/rs/ext/ParamConverter.html)
/ [ParamConverterProvider](https://docs.oracle.com/javaee/7/api/javax/ws/rs/ext/ParamConverterProvider.html) to make
REST @PathParams work (automatically configured by
the [`@Provider`](https://docs.oracle.com/javaee/7/api/javax/ws/rs/ext/Provider.html) annotation)
* a Jackson module containing Serializer/Deserializer to convert IDs in object bodys.**You need to manually customize the Jackson
Databind [`ObjectMapper`](https://fasterxml.github.io/jackson-databind/javadoc/2.7/com/fasterxml/jackson/databind/ObjectMapper.html)
.**Fortunately, There's a module for that:
```java
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.honoluluhenk.idclass.integration.jackson.IDTypeModule;class MyObjectMapperCustomizer {
void customize(ObjectMapper om) {
om.registerModule(new IDTypeModule());
}
}
```Now you can use it in all possible places in JAX-RS ressources/DTOs:
```java
class JaxHello {
private ID entityID;
private String name;
private Map, SomeEntity> entityMap;
// getters/setters omitted for brevity
}@Path("hello")
public class HelloResource {@POST
@Path("{id}")
public JaxHello sayHello(@PathParam("id") ID entityID) {
return someService.findEntity(entityID);
}
}
```### JPA/Hibernate Integration
Install using maven (also pulls in the basic ID class):
```xml
com.github.honoluluhenk.id-class
id-class-jpa-hibernate-integration
${id-class-parent.version}
```
**You need to declare dependencies to hibernate yourself (so you don't end up in dependency hell)!**
No you can start using the converter by attaching the
Hibernate [`@Type` or `@TypeDef` annotation](https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#basic-custom-type)
to the field in your entity:```java
import com.github.honoluluhenk.idclass.ID;
import org.hibernate.annotations.Type;@Entity
public class SomeEntity {
@Id
@Type(type = "com.github.honoluluhenk.idclass.integration.jpahibernate.IDType")
private ID id;// ...
}
```### JPA EntityManager enhancements
Install using maven (also pulls in id-class-jpa-hibernate-integration and the basic id-class).
```xml
com.github.honoluluhenk.id-class
id-class-jpa22-smartentitymanager
${id-class-parent.version}
```
This package enhances the standard JPA EntityManager so you can use the ID classes directly.
This also works with [Spring-Data](https://spring.io/projects/spring-data-jpa)!
```java
import com.github.honoluluhenk.idclass.ID;
import com.github.honoluluhenk.idclass.integration.jpahibernate.SmartEntityManager;@RequestScoped
@Transactional
class MyDAO {@PersistenceContext
private EntityManager em;private SmartEntityManager db() {
return new SmartEntityManager(em);
}// easier in the long run: implement your own @Producer and directly inject here:
// @Inject
// private SmartEntityManager sem;public MyEntity findById(ID entityID) {
return db()
.find(entityID);
}// also implemented: Java8 Optionals:
public Optional findOneByID(ID entityID) {
return db()
.findOne(entityID);
// same for Query/TypedQuery/StoreProcedureQuery: query.getSoleResult()
}
}```
SmartEntityManager might also be injected via e.g. your own @Produce method (CDI) or a Spring FactoryBean.
Example for a CDI producer:
```java
import javax.enterprise.inject.Produces;import com.github.honoluluhenk.idclass.integration.jpahibernate.SmartEntityManager;
@ApplicationScoped
public class SmartEntityManagerProducer {
@PersistenceContext
EntityManager defaultEntitymanager;@Produces
@RequestScoped
public SmartEntityManager produceSmartEntityManager() {
return new SmartEntityManager(defaultEntitymanager);
}
}
```## Credits
Thanks to [Fabio](https://github.com/xfh) for this great idea a long time ago!
## License
[GNU Lesser General Public License V3 (LGPLv3)](https://www.gnu.org/licenses/lgpl-3.0.html), see [LICENSE](LICENSE).