arakoodev / FlySpring

Developer-friendly Spring Boot flavor. Supercharged cli "flyfly" to make you fall in love with Java again
MIT License
7 stars 7 forks source link

use tsid #37

Open sandys opened 1 year ago

sandys commented 1 year ago

https://github.com/vladmihalcea/hypersistence-utils

https://github.com/vladmihalcea/hypersistence-utils/issues/526

sandys commented 1 year ago

To use Time-Sorted Unique Identifiers (TSID) as the primary key for Hibernate entities, you can create a custom ID generator. Here's how to set up the example: To rewrite the previous example using Java records and Hibernate without JPA, you can follow these steps:

  1. Update your pom.xml with the required dependencies:
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-groovy-templates</artifactId>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.6.3.Final</version>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>net.logstash.logback</groupId>
        <artifactId>logstash-logback-encoder</artifactId>
        <version>6.6</version>
    </dependency>
</dependencies>
  1. Create a hibernate.cfg.xml file in the src/main/resources folder with the following content:
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">org.h2.Driver</property>
        <property name="hibernate.connection.url">jdbc:h2:mem:testdb</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password"></property>
        <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <mapping class="com.example.manualconfig.Person"/>
    </session-factory>
</hibernate-configuration>
  1. Create a HibernateUtil class to manage the SessionFactory:
package com.example.manualconfig;

import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
                    .configure("hibernate.cfg.xml")
                    .build();
            Metadata metadata = new MetadataSources(standardRegistry)
                    .getMetadataBuilder()
                    .build();
            return metadata.getSessionFactoryBuilder().build();
        } catch (Exception e) {
            throw new ExceptionInInitializerError("Error building SessionFactory: " + e);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}
  1. Create a Person record class with the TsidGenerator as the ID generator:
package com.example.manualconfig;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public record Person(
        @Id
        @GeneratedValue(generator = "tsid-generator")
        @GenericGenerator(name = "tsid-generator", strategy = "com.example.manualconfig.TsidGenerator")
        String id,
        String name) {
}
  1. Modify the MyController class to include endpoints for creating and retrieving Person entities using Hibernate:
@RestController
public class MyController {

    private final MyService myService;
    private static final Logger logger = LoggerFactory.getLogger(MyController.class);

    @Autowired
    public MyController(MyService myService) {
        this.myService = myService;
    }

    @GetMapping("/")
    public String hello() {
        return myService.getMessage();
    }

    @GetMapping("/log")
    public String log() {
        logger.trace("This is a TRACE level log message");
        logger.debug("This is a DEBUG level log message");
        logger.info("This is an INFO level log message");
        logger.warn("This is a WARN level log message");
        logger.error("This is an ERROR level log message");

        return "Logged messages with different severity levels";
    }

    @PostMapping("/person")
    public Person createPerson(@RequestParam String name) {
        Person person = new Person(null, name);
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            Transaction transaction = session.beginTransaction();
            session.save(person);
            transaction.commit();
        }
        return person;
    }

    @GetMapping("/person/{id}")
    public Person getPerson(@PathVariable String id) {
        Person person;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            person = session.get(Person.class, id);
        }
        return person;
    }
}

Now, when you run the ManualConfigApplication class as a Java application, you can create and retrieve Person entities with TSID as the primary key. To create a new person, send a POST request to http://localhost:8080/person with the name parameter. To retrieve a person by ID, send a GET request to http://localhost:8080/person/{id}, replacing {id} with the actual TSID.