Hibernate: Difference between revisions
Jump to navigation
Jump to search
(27 intermediate revisions by the same user not shown) | |||
Line 10: | Line 10: | ||
<source lang="java"> | <source lang="java"> | ||
@Id | @Id | ||
@Column(name = "code", length = | @Column(name = "code", length = 6) | ||
@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) | ||
@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"; // 0 => Z | 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_2_MIN = "36"; // 10 => ZZ | ||
public static final String DIGIT_3_MIN = "1296"; // 100 => ZZZ | 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"; // 10,000 => ZZ,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_6_MIN = "60466176"; // 100,000 => ZZZ,ZZZ | ||
Line 55: | Line 55: | ||
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(( | 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( | 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);
| |
| |