Hibernate: Difference between revisions

From Chorke Wiki
Jump to navigation Jump to search
 
(28 intermediate revisions by the same user not shown)
Line 10: Line 10:
<source lang="java">
<source lang="java">
@Id
@Id
@Column(name = "code", length = 8)
@Column(name = "code", length = 6)
//@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "page_sqn")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "page_sqn")
//@SequenceGenerator(name = "page_sqn", sequenceName = "page_sqn", initialValue = 60466176, allocationSize = 1)
//@SequenceGenerator(name = "page_sqn", sequenceName = "page_sqn", initialValue = 60466176, allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "page_sqn")
@GenericGenerator(name  = "page_sqn", strategy = "org.chorke.academia.core.entity.Base36Style", parameters = {
@GenericGenerator(name  = "page_sqn", strategy = "org.chorke.academia.core.entity.Base36Style", parameters = {
     @Parameter(name = Base36Style.INITIAL_VALUE,  value = Base36Style.DIGIT_6_MIN),
     @Parameter(name = Base36Style.INITIAL_VALUE,  value = Base36Style.DIGIT_6_MIN),
Line 22: Line 21:
</source>
</source>


<source lang="java">
<source lang="java" highlight="15-17,34,41">
package org.chorke.academia.core.entity;
package org.chorke.academia.core.entity;


Line 36: Line 35:


public class Base36Style extends SequenceStyleGenerator {
public class Base36Style extends SequenceStyleGenerator {
    private static final Logger LOG = LoggerFactory.getLogger(Base36Style.class);
     public static final String ALLOCATION_SIZE = INCREMENT_PARAM;
     public static final String ALLOCATION_SIZE = INCREMENT_PARAM;
     public static final String SEQUENCE_NAME = SEQUENCE_PARAM;
     public static final String SEQUENCE_NAME   = SEQUENCE_PARAM;
     public static final String INITIAL_VALUE = INITIAL_PARAM;
     public static final String INITIAL_VALUE   = INITIAL_PARAM;
     public static final int RADIX = 36;
     public static final int   RADIX = 36;


     public static final String DIGIT_1_MIN = "0";
     public static final String DIGIT_1_MIN = "0";               //            0 =>            Z
     public static final String DIGIT_2_MIN = "36";
     public static final String DIGIT_2_MIN = "36";             //          10 =>            ZZ
     public static final String DIGIT_3_MIN = "1296";
     public static final String DIGIT_3_MIN = "1296";           //          100 =>          ZZZ
     public static final String DIGIT_4_MIN = "46656";
     public static final String DIGIT_4_MIN = "46656";           //        1,000 =>        Z,ZZZ
     public static final String DIGIT_5_MIN = "1679616";
     public static final String DIGIT_5_MIN = "1679616";         //      10,000 =>        ZZ,ZZZ
     public static final String DIGIT_6_MIN = "60466176";
     public static final String DIGIT_6_MIN = "60466176";       //      100,000 =>      ZZZ,ZZZ
     public static final String DIGIT_7_MIN = "2176782336";
     public static final String DIGIT_7_MIN = "2176782336";     //    1,000,000 =>    Z,ZZZ,ZZZ
     public static final String DIGIT_8_MIN = "78364164096";
     public static final String DIGIT_8_MIN = "78364164096";     //  10,000,000 =>    ZZ,ZZZ,ZZZ
     public static final String DIGIT_9_MIN = "2821109907456";
     public static final String DIGIT_9_MIN = "2821109907456";   //  100,000,000 =>  ZZZ,ZZZ,ZZZ
     public static final String DIGIT_X_MIN = "101559956668416";
     public static final String DIGIT_X_MIN = "101559956668416"; //1,000,000,000 => Z,ZZZ,ZZZ,ZZZ


     @Override
     @Override
     public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
     public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
         Serializable nextval = super.generate(session, object);
         Serializable nextval = super.generate(session, object);
         String base36 = Long.toString((long) nextval, RADIX);
         String base36 = Long.toString((Long) nextval, RADIX);
        LOG.debug("Base36: {}", base36.toUpperCase());
         return base36.toUpperCase();
         return base36.toUpperCase();
     }
     }
Line 61: Line 62:
     @Override
     @Override
     public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
     public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
         super.configure(type, params, serviceRegistry);
         super.configure(LongType.INSTANCE, params, serviceRegistry);
     }
     }
}
}
Line 118: Line 119:
! Sybase Anywhere
! Sybase Anywhere
| <code>✓</code> || <code>✓</code> || <code>✓</code>
| <code>✓</code> || <code>✓</code> || <code>✓</code>
|}
==Date Time==
<source lang="java">
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
class Playground {
    public static void main(String[ ] args) {
        System.out.println("Yesterday Min: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).minusDays(1L));
        System.out.println("Yesterday Max: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).minusNanos(1L));
        System.out.println("Yesterday Max: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).minusDays(1L).plusDays(1L).minusNanos(1L));
        System.out.println("Yesterday Max: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).minusDays(1L).plusHours(24).minusNanos(1L));
        System.out.println();
        System.out.println("Today    Min: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS));
        System.out.println("Today    Max: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).plusDays(1L).minusNanos(1L));
        System.out.println("Today    Max: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).plusHours(24).minusNanos(1L));
        System.out.println();
        System.out.println("Tomorrow Min: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).plusDays(1L));
        System.out.println("Tomorrow Max: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).plusDays(2L).minusNanos(1L));
        System.out.println("Tomorrow Max: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).plusHours(48).minusNanos(1L));
    }
}
</source>
==Knowledge==
{|
| valign="top" colspan="2" |
<source lang='java'>
import org.hibernate.Session;
Session session = (Session) entityManager.getDelegate();
Page<Country> countries = countryRepo.findAll(page);
countries = countries.map(country -> {
    session.evict(country);
    if (ObjectUtils.isEmpty(country.getContinent())) {
        Continent continent = continentRepo.findById(country.getContinentCode());
        country.setContinent(continent);
        return country;
    } else return country;
});
</source>
|-
| colspan="2" |
----
|-
| valign="top" colspan="2" |
<source lang='java'>
@PersistenceContext
EntityManager entityManager;
if (entityManager.contains(country)) entityManager.detach(country);
//  entityManager.detach(country);
</source>
|-
| colspan="2" |
----
|-
| valign="top" |
| valign="top" |
|}
|}


Line 135: Line 202:


| valign="top" |
| valign="top" |
* [https://programmer.group/oracle-to-mysql-database-migration-primary-key-generation-policy-replacement.html Using MySQL table to simulate Oracle Sequence]
* [https://stackoverflow.com/questions/28539915/ Multiple SequenceGenerator in Hibernate Entity]
* [https://coderanch.com/t/573996/databases/SequenceGenerator-MySql-Database <code>@SequenceGenerator</code> for MySql Database]
* [https://vladmihalcea.com/why-you-should-never-use-the-table-identifier-generator-with-jpa-and-hibernate/ Never use the TABLE identifier generator]
* [https://vladmihalcea.com/why-you-should-never-use-the-table-identifier-generator-with-jpa-and-hibernate/ Never use the TABLE identifier generator]
* [https://thorben-janssen.com/custom-sequence-based-idgenerator/ Custom Sequence Based ID Generator]
* [https://thorben-janssen.com/custom-sequence-based-idgenerator/ Custom Sequence Based ID Generator]
Line 142: Line 212:
* [http://www.dbunit.org/howto.html DBUnit]
* [http://www.dbunit.org/howto.html DBUnit]
* [[Locale]]
* [[Locale]]
|}
----
{|
| valign="top" |
* [https://stackoverflow.com/questions/13370221/ PersistentObjectException: detached entity thrown by JPA]
* [https://stackoverflow.com/questions/21708339/ Prevent Jackson to Serialize <code>Non-Fetched Lazy</code> Objects]
* [https://stackoverflow.com/questions/57168773/ Does JPA delete also remove large objects of Blob fields]
* [https://stackoverflow.com/questions/31446/ Detach an entity from JPA/EJB3 persistence context]
* [https://www.baeldung.com/spring-data-jpa-stored-procedures Calling Stored Procedures from Spring Data JPA]
* [https://vladmihalcea.com/ Vlad Mihalcea the Java Champion]
* [https://github.com/eugenp/tutorials/blob/master/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/repository/CarRepository.java Example of Stored Procedure]
* [[MapStruct]]
* [[Liquibase]]
| valign="top" |
* [https://stackoverflow.com/questions/45973070/ Spring JPA ExampleMatcher compare date condition]
* [https://stackoverflow.com/questions/60112439 Difference btn. <code>evict</code> and <code>detach</code> in hibernate]
* [https://stackoverflow.com/questions/65478350/ Column type is JSON but expression is Varchar]
* [https://stackoverflow.com/questions/39620317/ Map a JSON column with H2 & Spring JPA]
* [https://stackoverflow.com/questions/2311125/ Ignore Hibernate <code>@Where</code> annotation]
* [https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html Java » ISO <code>DateTimeFormatter</code>]
* [https://stackoverflow.com/questions/7700071/  Use  <code>@Where</code> in Hibernate]
* [[Lombok]]


|}
|}

Latest revision as of 18:05, 1 February 2024

Replacements

java.util.Date     => java.time.Instant
java.sql.Timestamp => java.time.Instant
java.sql.Date      => java.time.LocalDate
java.sql.Time      => java.time.LocalTime

The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).All three java.time.Local… classes are all lacking any concept of time zone or offset-from-UTC.

Sequence Style

@Id
@Column(name = "code", length = 6)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "page_sqn")
//@SequenceGenerator(name = "page_sqn", sequenceName = "page_sqn", initialValue = 60466176, allocationSize = 1)
@GenericGenerator(name  = "page_sqn", strategy = "org.chorke.academia.core.entity.Base36Style", parameters = {
    @Parameter(name = Base36Style.INITIAL_VALUE,   value = Base36Style.DIGIT_6_MIN),
    @Parameter(name = Base36Style.SEQUENCE_NAME,   value = "page_sqn"),
    @Parameter(name = Base36Style.ALLOCATION_SIZE, value = "1"),
})
private String code;
package org.chorke.academia.core.entity;

import java.io.Serializable;
import java.util.Properties;

import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;

public class Base36Style extends SequenceStyleGenerator {
    private static final Logger LOG = LoggerFactory.getLogger(Base36Style.class);
    public static final String ALLOCATION_SIZE = INCREMENT_PARAM;
    public static final String SEQUENCE_NAME   = SEQUENCE_PARAM;
    public static final String INITIAL_VALUE   = INITIAL_PARAM;
    public static final int    RADIX = 36;

    public static final String DIGIT_1_MIN = "0";               //            0 =>             Z
    public static final String DIGIT_2_MIN = "36";              //           10 =>            ZZ
    public static final String DIGIT_3_MIN = "1296";            //          100 =>           ZZZ
    public static final String DIGIT_4_MIN = "46656";           //        1,000 =>         Z,ZZZ
    public static final String DIGIT_5_MIN = "1679616";         //       10,000 =>        ZZ,ZZZ
    public static final String DIGIT_6_MIN = "60466176";        //      100,000 =>       ZZZ,ZZZ
    public static final String DIGIT_7_MIN = "2176782336";      //    1,000,000 =>     Z,ZZZ,ZZZ
    public static final String DIGIT_8_MIN = "78364164096";     //   10,000,000 =>    ZZ,ZZZ,ZZZ
    public static final String DIGIT_9_MIN = "2821109907456";   //  100,000,000 =>   ZZZ,ZZZ,ZZZ
    public static final String DIGIT_X_MIN = "101559956668416"; //1,000,000,000 => Z,ZZZ,ZZZ,ZZZ

    @Override
    public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
        Serializable nextval = super.generate(session, object);
        String base36 = Long.toString((Long) nextval, RADIX);
        LOG.debug("Base36: {}", base36.toUpperCase());
        return base36.toUpperCase();
    }

    @Override
    public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
        super.configure(LongType.INSTANCE, params, serviceRegistry);
    }
}

Challenges

Database Auto Increment Sequence Usable
DB2/LUW
DB2/z
PostgreSQL
Derby
Firebird
H2
HyperSQL
INGRES
Informix
MariaDB
MySQL
Oracle
Sql Server
SQLite
Sybase
Sybase Anywhere

Date Time

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

class Playground {
    public static void main(String[ ] args) {
        System.out.println("Yesterday Min: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).minusDays(1L));
        System.out.println("Yesterday Max: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).minusNanos(1L));
        System.out.println("Yesterday Max: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).minusDays(1L).plusDays(1L).minusNanos(1L));
        System.out.println("Yesterday Max: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).minusDays(1L).plusHours(24).minusNanos(1L));

        System.out.println();
        System.out.println("Today    Min: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS));
        System.out.println("Today    Max: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).plusDays(1L).minusNanos(1L));
        System.out.println("Today    Max: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).plusHours(24).minusNanos(1L));

        System.out.println();
        System.out.println("Tomorrow Min: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).plusDays(1L));
        System.out.println("Tomorrow Max: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).plusDays(2L).minusNanos(1L));
        System.out.println("Tomorrow Max: " + LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).plusHours(48).minusNanos(1L));
    }
}

Knowledge

import org.hibernate.Session;

Session session = (Session) entityManager.getDelegate();
Page<Country> countries = countryRepo.findAll(page);
countries = countries.map(country -> {
    session.evict(country);
    if (ObjectUtils.isEmpty(country.getContinent())) {
        Continent continent = continentRepo.findById(country.getContinentCode());
        country.setContinent(continent);
        return country;
    } else return country;
});

@PersistenceContext
EntityManager entityManager;

if (entityManager.contains(country)) entityManager.detach(country);
//  entityManager.detach(country);

References