Javax.persistence.Entity - Yash-777/MyWorld GitHub Wiki
Log4jdbc to Log SQL Queries stackoverflow post
-
Candrews
com.integralblue
<dependency>
<groupId>com.integralblue</groupId>
<artifactId>log4jdbc-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
hibernate.type:TRACE;
hibernate.format_sql:true;
hibernate.show_sql:true;
logging.level.org.hibernate.SQL:DEBUG;
logging.level.org.hibernate.type:TRACE;
Loading class
com.mysql.jdbc.Driver'. This is deprecated. The new driver class is
com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
you can set correct driver by the follwing properties.
log4jdbc.drivers=com.mysql.cj.jdbc.Driver
log4jdbc.auto.load.popular.drivers=false
org.bgee.log4jdbc-log4j2
`org.bgee.log4jdbc-log4j2` | `net.disy.oss` [forked from org.bgee.log4jdbc-log4j2](https://github.com/DisyInformationssysteme/log4jdbc) |
---|---|
|
|
A transaction is a set of logically related operations.
Transactions are everywhere
/widely-used
in today’s enterprise/business systems. A transaction is a collection of read
/write
operations succeeding only if all contained operations succeed.
DBMS Transaction States
States through which a transaction goes during its lifetime. These are the states which tell about the current state of the Transaction and also tell how we will further do the processing in the transactions. These states govern the rules which decide the fate of the transaction whether it will commit or abort.
They also use Transaction log. Transaction log is a file maintain by recovery management component to record all the activities of the transaction. After commit is done transaction log file is removed.
Operations | Transaction States |
---|---|
In a relational database, every SQL statement must execute in the scope of a transaction. Without defining the transaction boundaries explicitly, the database is going to use an implicit transaction which is wraps around every individual statement. The implicit transaction begins before the statement is executed and end (commit or rollback) after the statement is executed.
The implicit transaction mode is commonly known as autocommit.
For an enterprise application, the auto-commit mode is something you’d generally want to avoid since it has serious performance penalties, and it doesn’t allow you to include multiple DML operations in a single atomic Unit of Work.
Database transactions are defined by the four properties known as ACID.
Property | Responsibility for maintaining properties | DBMS |
---|---|---|
Atomicity | Transaction Manager | By this, we mean that either the entire transaction takes place at once or doesn’t happen at all. There is no midway i.e. transactions do not occur partially. Each transaction is considered as one unit and either runs to completion or is not executed at all. It involves the following two operations.
|
Consistency | Application programmer | This means that integrity constraints must be maintained so that the database is consistent before and after the transaction. It refers to the correctness of a database. |
Isolation | Concurrency Control Manager | This property ensures that multiple transactions can occur concurrently without leading to the inconsistency of the database state. Transactions occur independently without interference. Changes occurring in a particular transaction will not be visible to any other transaction until that particular change in that transaction is written to memory or has been committed. |
Durability | Recovery Manager | This property ensures that once the transaction has completed execution, the updates and modifications to the database are stored in and written to disk and they persist even if a system failure occurs. These updates now become permanent and are stored in non-volatile memory. The effects of the transaction, thus, are never lost. If our system is suddenly affected by a system crash or a power outage, then all unfinished committed transactions may be replayed. |
ACID Properties in DBMSgeeksforgeeks.org
Consider the following transaction T consisting of T1 and T2: Transfer of 100 from account X to account Y.
Example:
Atomicity
If the transaction fails after completion of T1 but before completion of T2.( say, after write(X) but before write(Y)), then the amount has been deducted from X but not added to Y. This results in an inconsistent database state. Therefore, the transaction must be executed in its entirety in order to ensure the correctness of the database state.
Consistency:
The total amount before and after the transaction must be maintained.
Total before T occurs = 500 + 200 = 700.
Total after T occurs = 400 + 300 = 700.
Therefore, the database is consistent. Inconsistency occurs in case T1 completes but T2 fails. As a result, T is incomplete.
Isolation:
Let X= 500, Y = 500.
Consider two transactions T and T”.
Suppose T has been executed till Read (Y) and then T’’ starts. As a result, interleaving of operations takes place due to which T’’ reads the correct value of X but the incorrect value of Y and sum computed by
T’’: (X+Y = 50, 000+500=50, 500)
is thus not consistent with the sum at end of the transaction:
T: (X+Y = 50, 000 + 450 = 50, 450).
This results in database inconsistency, due to a loss of 50 units. Hence, transactions must take place in isolation and changes should be visible only after they have been made to the main memory.
All managed entity state transitions are translated to associated database statements when the current Persistence Context gets flushed. Hibernate’s flush behavior is not always as obvious as one might think.
Hibernate tries to defer the Persistence Context flushing up until the last possible moment. This strategy has been traditionally known as transactional write-behind.
The write-behind is more related to Hibernate flushing rather than any logical or physical transaction. During a transaction, the flush may occur multiple times.
The flushed changes are visible only for the current database transaction. Until the current transaction is committed, no change is visible by other concurrent transactions.
The persistence context, also known as the first level cache
, acts as a buffer between the current entity state transitions and the database.
In caching theory, the write-behind synchronization requires that all changes happen against the cache, whose responsibility is to eventually synchronize with the backing store.
Caching
Caching is all about application performance optimization and it sits between your application and the database to avoid the number of database hits as many as possible to give a better performance for performance critical applications.
One of the primary concerns of mappings between a database and our Java application is performance. This is the common concern of the all guys who working with hibernate and spent the more time in ORM tools for performance-enhancing changes to particular queries and retrievals.
Hibernate cache | Image, stackoverflow |
---|---|
|
|
DataBase - DataSourceConfig
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "rdbmsEntityManager",
transactionManagerRef = "transactionManager",
basePackages = { "com.github.myworld.repositories" }
)
@ConditionalOnProperty(value = "datasourceType", havingValue = "RDBMS", matchIfMissing = false)
public class DataSourceConfig2 {
static String packagesToScan = "com.github.myworld.entities";
static boolean useL2Cache = false, useQueryCache = false;
@Autowired
Environment env;
// @Bean
// @ConfigurationProperties(prefix = "app.datasource.myworld")
// public DataSourceProperties getDataSourceProperties() {
// //spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL8Dialect
// return new DataSourceProperties();
// }
/*
app.datasource.myworld.url=jdbc:mysql://localhost:3306/flywaydb?createDatabaseIfNotExist=true
app.datasource.myworld.username=root
app.datasource.myworld.password=root
app.datasource.myworld.driver-class-name=com.mysql.cj.jdbc.Driver
*/
@Bean(name = "hikariDataSource")
public DataSource getDataSourceHikariConfig() {
String propertiesPrefix = "app.datasource.myworld.";
String jdbcURL = env.getProperty(propertiesPrefix+"url", String.class);
String driverClassName = env.getProperty(propertiesPrefix+"driver-class-name", String.class);
String username = env.getProperty(propertiesPrefix+"username", String.class);
String password = env.getProperty(propertiesPrefix+"password", String.class);
com.zaxxer.hikari.HikariConfig hikariConfig = new com.zaxxer.hikari.HikariConfig();
hikariConfig.setJdbcUrl( jdbcURL );
hikariConfig.setDriverClassName( driverClassName );
hikariConfig.setUsername( username );
hikariConfig.setPassword( password );
hikariConfig.setConnectionTimeout(10000L);
hikariConfig.setIdleTimeout(10000L);
hikariConfig.setMaxLifetime(1000L);
hikariConfig.setKeepaliveTime(1000L);
hikariConfig.setMaximumPoolSize(100);
hikariConfig.setMinimumIdle(30);
return new com.zaxxer.hikari.HikariDataSource( hikariConfig );
// return getDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
@Bean
public LocalContainerEntityManagerFactoryBean rdbmsEntityManager() { // entityManagerFactoryRef = "rdbmsEntityManager"
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource( getDataSourceHikariConfig() );
em.setPackagesToScan( packagesToScan );
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
//properties.put("hibernate.allow_update_outside_transaction",true);
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
// With the following two properties, we’ll tell Hibernate that L2 caching is enabled, and give it the name of the region factory class
if ( useL2Cache ) { // https://www.baeldung.com/hibernate-second-level-cache
properties.put("hibernate.cache.use_second_level_cache", true);
properties.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory");// Impl of RegionFactory
if ( useQueryCache ) {
properties.put("hibernate.cache.use_query_cache", true);
}
}
em.setJpaPropertyMap(properties);
return em;
}
@Bean
public PlatformTransactionManager transactionManager() { // transactionManagerRef = "transactionManager"
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory( rdbmsEntityManager().getObject() );
return transactionManager;
}
// JDBC style - Template's provide implementation of JdbcOperations
@Bean
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate( getDataSourceHikariConfig() );
}
@Bean
public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
return new NamedParameterJdbcTemplate( getDataSourceHikariConfig() );
}
}
Java Persistence API comes with a thorough concurrency control mechanism, supporting both implicit and explicit locking. The implicit locking mechanism is straightforward and it relies on:
- Optimistic locking: Entity state changes can trigger a version incrementation
- Row-level locking: Based on the current running transaction isolation level, the
INSERT/UPDATE/DELETE
statements may acquire exclusive row locks
@javax.persistence.Version
(OptimisticLockException)
The following types are supported for version properties: int, Integer, short, Short, long, Long, java.sql.Timestamp.
@Entity
public class MyEntity implements Serializable {
// ...
@Version
@Column(name = "optlockversion"), columnDefinition = "integer DEFAULT 0", nullable = false)
private long version = 0L;
// ...
}