Merge branch 'eugenp:master' into master

This commit is contained in:
Wynn Teo 2024-02-12 19:09:23 +08:00 committed by GitHub
commit 0b967edb88
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
49 changed files with 224 additions and 229 deletions

View File

@ -18,6 +18,12 @@
<artifactId>transactions-jdbc</artifactId>
<version>${atomikos-version}</version>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jta</artifactId>
<version>${atomikos-version}</version>
<classifier>jakarta</classifier>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jms</artifactId>
@ -90,10 +96,10 @@
</dependencies>
<properties>
<atomikos-version>5.0.6</atomikos-version>
<spring-version>5.1.6.RELEASE</spring-version>
<hibernate.version>5.4.3.Final</hibernate.version>
<spring-data-jpa.version>1.11.23.RELEASE</spring-data-jpa.version>
<atomikos-version>6.0.0</atomikos-version>
<spring-version>6.1.2</spring-version>
<hibernate.version>6.4.2.Final</hibernate.version>
<spring-data-jpa.version>3.2.2</spring-data-jpa.version>
<activemq-core.version>5.7.0</activemq-core.version>
<derby.version>10.8.1.2</derby.version>
<jta.version>1.1</jta.version>

View File

@ -1,17 +1,14 @@
package com.baeldung.atomikos.spring.config;
import java.util.Properties;
import javax.transaction.SystemException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.jta.JtaTransactionManager;
import com.atomikos.icatch.jta.UserTransactionManager;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import com.baeldung.atomikos.spring.Application;
import jakarta.transaction.SystemException;
import java.util.Properties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.jta.JtaTransactionManager;
@Configuration
@EnableTransactionManagement
@ -46,7 +43,7 @@ public class Config {
}
@Bean(initMethod = "init", destroyMethod = "close")
public UserTransactionManager userTransactionManager() throws SystemException {
public UserTransactionManager userTransactionManager() throws jakarta.transaction.SystemException {
UserTransactionManager userTransactionManager = new UserTransactionManager();
userTransactionManager.setTransactionTimeout(300);
userTransactionManager.setForceShutdown(true);

View File

@ -29,13 +29,13 @@ public class Application {
String orderId = UUID.randomUUID()
.toString();
Inventory inventory = inventoryRepository.findOne(productId);
Inventory inventory = inventoryRepository.getReferenceById(productId);
inventory.setBalance(inventory.getBalance() - amount);
inventoryRepository.save(inventory);
Order order = new Order();
order.setOrderId(orderId);
order.setProductId(productId);
order.setAmount(new Long(amount));
order.setAmount( Long.valueOf(amount));
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Order>> violations = validator.validate(order);

View File

@ -1,6 +1,6 @@
package com.baeldung.atomikos.spring.jpa.config;
import javax.transaction.SystemException;
import jakarta.transaction.SystemException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -1,8 +1,8 @@
package com.baeldung.atomikos.spring.jpa.inventory;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name = "INVENTORY")

View File

@ -2,7 +2,7 @@ package com.baeldung.atomikos.spring.jpa.inventory;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import jakarta.persistence.EntityManagerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -1,8 +1,8 @@
package com.baeldung.atomikos.spring.jpa.order;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.Max;
@Entity

View File

@ -2,7 +2,7 @@ package com.baeldung.atomikos.spring.jpa.order;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import jakarta.persistence.EntityManagerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -72,7 +72,7 @@ public class ApplicationUnitTest {
private static long getBalance(InventoryRepository inventoryRepository, String productId) throws Exception {
return inventoryRepository.findOne(productId)
return inventoryRepository.getReferenceById(productId)
.getBalance();
}

View File

@ -15,7 +15,7 @@
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
@ -25,7 +25,7 @@
<version>${h2.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-spatial</artifactId>
<version>${hibernate.version}</version>
</dependency>
@ -45,7 +45,7 @@
<version>${mariaDB4j.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-testing</artifactId>
<version>${hibernate.version}</version>
</dependency>
@ -82,6 +82,7 @@
<mysql.version>8.2.0</mysql.version>
<mariaDB4j.version>2.6.0</mariaDB4j.version>
<geodb.version>0.9</geodb.version>
<hibernate.version>6.4.2.Final</hibernate.version>
</properties>
</project>

View File

@ -9,12 +9,16 @@ import java.util.List;
import jakarta.persistence.OptimisticLockException;
import jakarta.persistence.PersistenceException;
import org.h2.jdbc.JdbcSQLDataException;
import org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException;
import org.h2.jdbc.JdbcSQLSyntaxErrorException;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.NonUniqueObjectException;
import org.hibernate.PropertyValueException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.StaleObjectStateException;
import org.hibernate.StaleStateException;
import org.hibernate.Transaction;
import org.hibernate.cfg.AvailableSettings;
@ -132,8 +136,8 @@ public class HibernateExceptionUnitTest {
@Test
public void givenMissingTable_whenEntitySaved_thenSQLGrammarException() {
thrown.expectCause(isA(SQLGrammarException.class));
thrown.expectMessage("could not prepare statement");
thrown.expectCause(isA(JdbcSQLSyntaxErrorException.class));
thrown.expectMessage("Table \"PRODUCT\" not found (this database is empty); SQL statement");
Configuration cfg = getConfiguration();
cfg.addAnnotatedClass(Product.class);
@ -161,8 +165,8 @@ public class HibernateExceptionUnitTest {
@Test
public void givenMissingTable_whenQueryExecuted_thenSQLGrammarException() {
thrown.expectCause(isA(SQLGrammarException.class));
thrown.expectMessage("could not prepare statement");
thrown.expectCause(isA(JdbcSQLSyntaxErrorException.class));
thrown.expectMessage("Table \"NON_EXISTING_TABLE\" not found");
Session session = sessionFactory.openSession();
NativeQuery<Product> query = session.createNativeQuery("select * from NON_EXISTING_TABLE", Product.class);
@ -171,7 +175,7 @@ public class HibernateExceptionUnitTest {
@Test
public void whenDuplicateIdSaved_thenConstraintViolationException() {
thrown.expectCause(isA(ConstraintViolationException.class));
thrown.expectCause(isA(JdbcSQLIntegrityConstraintViolationException.class));
thrown.expectMessage("could not execute statement");
Session session = null;
@ -224,7 +228,7 @@ public class HibernateExceptionUnitTest {
public void givenEntityWithoutId_whenCallingSave_thenThrowIdentifierGenerationException() {
thrown.expect(isA(IdentifierGenerationException.class));
thrown.expectMessage("ids for this class must be manually assigned before calling save(): com.baeldung.hibernate.exception.Product");
thrown.expectMessage("Identifier of entity 'com.baeldung.hibernate.exception.ProductEntity' must be manually assigned before calling 'persist()");
Session session = null;
Transaction transaction = null;
@ -249,8 +253,8 @@ public class HibernateExceptionUnitTest {
@Test
public void givenQueryWithDataTypeMismatch_WhenQueryExecuted_thenDataException() {
thrown.expectCause(isA(DataException.class));
thrown.expectMessage("could not prepare statement");
thrown.expectCause(isA(JdbcSQLDataException.class));
thrown.expectMessage("Data conversion error converting \"wrongTypeId\"");
Session session = sessionFactory.openSession();
NativeQuery<Product> query = session.createNativeQuery("select * from PRODUCT where id='wrongTypeId'", Product.class);
@ -291,7 +295,7 @@ public class HibernateExceptionUnitTest {
@Test
public void whenDeletingADeletedObject_thenOptimisticLockException() {
thrown.expect(isA(OptimisticLockException.class));
thrown.expectMessage("Batch update returned unexpected row count from update");
thrown.expectMessage("Row was updated or deleted by another transaction");
thrown.expectCause(isA(StaleStateException.class));
Session session = null;
@ -327,8 +331,8 @@ public class HibernateExceptionUnitTest {
@Test
public void whenUpdatingNonExistingObject_thenStaleStateException() {
thrown.expectCause(isA(StaleStateException.class));
thrown.expectMessage("Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; statement executed: update PRODUCT set description=?, name=? where id=?");
thrown.expectCause(isA(StaleObjectStateException.class));
thrown.expectMessage("Row was updated or deleted by another transaction");
Session session = null;
Transaction transaction = null;
@ -409,9 +413,7 @@ public class HibernateExceptionUnitTest {
@Test
public void givenExistingEntity_whenIdUpdated_thenHibernateException() {
thrown.expect(isA(PersistenceException.class));
thrown.expectCause(isA(HibernateException.class));
thrown.expectMessage("identifier of an instance of com.baeldung.hibernate.exception.Product was altered");
thrown.expect(isA(HibernateException.class));
Session session = null;
Transaction transaction = null;

View File

@ -10,7 +10,7 @@ import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionPr
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
@SuppressWarnings("serial")
public class MapMultiTenantConnectionProvider extends AbstractMultiTenantConnectionProvider {
public class MapMultiTenantConnectionProvider extends AbstractMultiTenantConnectionProvider<String> {
private final Map<String, ConnectionProvider> connectionProviderMap = new HashMap<>();
@ -26,6 +26,7 @@ public class MapMultiTenantConnectionProvider extends AbstractMultiTenantConnect
.next();
}
@Override
protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) {
return connectionProviderMap.get(tenantIdentifier);

View File

@ -12,7 +12,7 @@ import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionPr
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
@SuppressWarnings("serial")
public class SchemaMultiTenantConnectionProvider extends AbstractMultiTenantConnectionProvider {
public class SchemaMultiTenantConnectionProvider extends AbstractMultiTenantConnectionProvider<String> {
private final ConnectionProvider connectionProvider;

View File

@ -179,7 +179,7 @@ public class SaveMethodsIntegrationTest {
.commit();
session.beginTransaction();
assertNull(person.getId());
assertNotNull(person.getId());
assertNotNull(mergedPerson.getId());
}

View File

@ -20,7 +20,7 @@
<version>${hsqldb.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
@ -34,6 +34,7 @@
<properties>
<hsqldb.version>2.7.1</hsqldb.version>
<h2.version>2.1.214</h2.version>
<hibernate.version>6.4.2.Final</hibernate.version>
</properties>
</project>

View File

@ -26,9 +26,8 @@ public class Author {
@Column(name = "name")
private String name;
@ManyToMany
@Cascade({ CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.PERSIST})
@JoinColumn(name = "book_id")
@ManyToMany(mappedBy = "authors")
private Set<Book> books = new HashSet<>();
public void addBook(Book book) {

View File

@ -1,6 +1,7 @@
package com.baeldung.hibernate.exception.transientobject.entity;
import jakarta.persistence.JoinTable;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
@ -29,7 +30,7 @@ public class Book {
@ManyToMany
@Cascade({ CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.PERSIST})
@JoinColumn(name = "author_id")
@JoinTable(joinColumns = { @JoinColumn(name = "author_id") })
private Set<Author> authors = new HashSet<>();
public void addAuthor(Author author) {

View File

@ -44,7 +44,7 @@ class NamedParameterNotBoundExceptionUnitTest {
query.list();
});
String expectedMessage = "Named parameter not bound";
String expectedMessage = "No argument for named parameter";
String actualMessage = exception.getMessage();
assertTrue(actualMessage.contains(expectedMessage));

View File

@ -15,7 +15,7 @@
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
@ -84,6 +84,7 @@
<properties>
<mysql.version>8.2.0</mysql.version>
<hibernate.version>6.4.2.Final</hibernate.version>
<mariaDB4j.version>2.6.0</mariaDB4j.version>
<spring-boot.version>3.0.4</spring-boot.version>
<h2.version>2.1.214</h2.version>

View File

@ -8,9 +8,9 @@
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<artifactId>parent-boot-3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-2</relativePath>
<relativePath>../../parent-boot-3</relativePath>
</parent>
<dependencies>
@ -19,8 +19,9 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>${jakarta.persistence.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
@ -29,6 +30,16 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</exclusion>
<exclusion>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
@ -36,33 +47,21 @@
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<artifactId>querydsl-jpa</artifactId>
<classifier>jakarta</classifier>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<artifactId>querydsl-apt</artifactId>
<classifier>jakarta</classifier>
<version>${querydsl.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/generated-sources</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
@ -86,11 +85,21 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>5.6.11.Final</version>
<version>${hibernate-jpamodelgen.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<querydsl.version>5.0.0</querydsl.version>
<jakarta.persistence.version>3.1.0</jakarta.persistence.version>
<apt-maven-plugin.version>1.1.3</apt-maven-plugin.version>
<spring-boot.repackage.skip>true</spring-boot.repackage.skip>
<hibernate-jpamodelgen.version>6.4.2.Final</hibernate-jpamodelgen.version>
</properties>
</project>

View File

@ -1,8 +1,8 @@
package com.baeldung.spring.data.persistence.customrepository.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import java.util.Objects;
@Entity

View File

@ -2,9 +2,9 @@ package com.baeldung.spring.data.persistence.customrepository.repository;
import com.baeldung.spring.data.persistence.customrepository.model.User;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.annotation.PostConstruct;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.Objects;
public class CustomUserRepositoryImpl implements CustomUserRepository {

View File

@ -1,9 +1,9 @@
package com.baeldung.spring.data.persistence.findbyvsfindallby.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import java.util.Objects;
@Entity

View File

@ -1,9 +1,9 @@
package com.baeldung.spring.data.persistence.saveperformance;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Book {

View File

@ -2,10 +2,10 @@ package com.baeldung.spring.data.persistence.search;
import java.util.Objects;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Student {

View File

@ -3,13 +3,13 @@ package com.baeldung.spring.data.persistence.springdatajpadifference.model;
import java.io.Serializable;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.NamedQuery;
import jakarta.persistence.Table;
@Entity
@Table(name = "employee")

View File

@ -2,7 +2,7 @@ package com.baeldung.spring.data.persistence.springdatajpadifference.springdata.
import java.util.Properties;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
import javax.sql.DataSource;
import org.springframework.boot.jdbc.DataSourceBuilder;

View File

@ -1,11 +1,11 @@
package com.baeldung.spring.data.persistence.springdatajpadifference.springdata.repository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.baeldung.spring.data.persistence.springdatajpadifference.model.Employee;
@Repository
public interface EmployeeRepositoryPagingAndSort extends PagingAndSortingRepository<Employee, Long> {
public interface EmployeeRepositoryPagingAndSort extends JpaRepository<Employee, Long> {
}

View File

@ -13,8 +13,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Sort;

View File

@ -7,15 +7,15 @@ import static org.junit.Assert.assertNull;
import java.util.Arrays;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.CriteriaUpdate;
import javax.persistence.criteria.Root;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaUpdate;
import jakarta.persistence.criteria.Root;
import org.junit.Before;
import org.junit.Test;

View File

@ -1194,8 +1194,8 @@
<exec-maven-plugin.version>3.1.0</exec-maven-plugin.version>
<java.version>1.8</java.version>
<log4j.version>1.2.17</log4j.version>
<jmh-core.version>1.36</jmh-core.version>
<jmh-generator.version>1.36</jmh-generator.version>
<jmh-core.version>1.37</jmh-core.version>
<jmh-generator.version>1.37</jmh-generator.version>
<maven-failsafe-plugin.version>3.1.2</maven-failsafe-plugin.version>
<commons-collections4.version>4.4</commons-collections4.version>
<commons-io.version>2.13.0</commons-io.version>

View File

@ -11,7 +11,8 @@
<parent>
<groupId>com.baeldung</groupId>
<artifactId>spring-security-modules</artifactId>
<artifactId>parent-boot-3</artifactId>
<relativePath>../../parent-boot-3</relativePath>
<version>0.0.1-SNAPSHOT</version>
</parent>
@ -46,16 +47,6 @@
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>${ehcache-core.version}</version>
<type>jar</type>
</dependency>
</dependencies>
<properties>
<ehcache-core.version>2.6.11</ehcache-core.version>
</properties>
</project>

View File

@ -4,8 +4,7 @@ import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cache.ehcache.EhCacheFactoryBean;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
@ -16,7 +15,7 @@ import org.springframework.security.acls.domain.AclAuthorizationStrategy;
import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl;
import org.springframework.security.acls.domain.ConsoleAuditLogger;
import org.springframework.security.acls.domain.DefaultPermissionGrantingStrategy;
import org.springframework.security.acls.domain.EhCacheBasedAclCache;
import org.springframework.security.acls.domain.SpringCacheBasedAclCache;
import org.springframework.security.acls.jdbc.BasicLookupStrategy;
import org.springframework.security.acls.jdbc.JdbcMutableAclService;
import org.springframework.security.acls.jdbc.LookupStrategy;
@ -31,21 +30,9 @@ public class ACLContext {
DataSource dataSource;
@Bean
public EhCacheBasedAclCache aclCache() {
return new EhCacheBasedAclCache(aclEhCacheFactoryBean().getObject(), permissionGrantingStrategy(), aclAuthorizationStrategy());
}
@Bean
public EhCacheFactoryBean aclEhCacheFactoryBean() {
EhCacheFactoryBean ehCacheFactoryBean = new EhCacheFactoryBean();
ehCacheFactoryBean.setCacheManager(aclCacheManager().getObject());
ehCacheFactoryBean.setCacheName("aclCache");
return ehCacheFactoryBean;
}
@Bean
public EhCacheManagerFactoryBean aclCacheManager() {
return new EhCacheManagerFactoryBean();
public SpringCacheBasedAclCache aclCache() {
final ConcurrentMapCache aclCache = new ConcurrentMapCache("acl_cache");
return new SpringCacheBasedAclCache(aclCache, permissionGrantingStrategy(), aclAuthorizationStrategy());
}
@Bean

View File

@ -1,9 +1,9 @@
package com.baeldung.acl.persistence.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name="system_message")

View File

@ -1,7 +1,7 @@
INSERT INTO acl_sid (id, principal, sid) VALUES
(1, 1, 'manager'),
(2, 1, 'hr'),
(3, 0, 'ROLE_EDITOR');
INSERT INTO acl_sid (principal, sid) VALUES
(1, 'manager'),
(1, 'hr'),
(0, 'ROLE_EDITOR');
INSERT INTO acl_class (id, class) VALUES
(1, 'com.baeldung.acl.persistence.entity.NoticeMessage');
@ -11,16 +11,16 @@ INSERT INTO system_message(id,content) VALUES
(2,'Second Level Message'),
(3,'Third Level Message');
INSERT INTO acl_object_identity (id, object_id_class, object_id_identity, parent_object, owner_sid, entries_inheriting) VALUES
(1, 1, 1, NULL, 3, 0),
(2, 1, 2, NULL, 3, 0),
(3, 1, 3, NULL, 3, 0);
INSERT INTO acl_object_identity (object_id_class, object_id_identity, parent_object, owner_sid, entries_inheriting) VALUES
(1, 1, NULL, 3, 0),
(1, 2, NULL, 3, 0),
(1, 3, NULL, 3, 0);
INSERT INTO acl_entry (id, acl_object_identity, ace_order, sid, mask, granting, audit_success, audit_failure) VALUES
(1, 1, 1, 1, 1, 1, 1, 1),
(2, 1, 2, 1, 2, 1, 1, 1),
(3, 1, 3, 3, 1, 1, 1, 1),
(4, 2, 1, 2, 1, 1, 1, 1),
(5, 2, 2, 3, 1, 1, 1, 1),
(6, 3, 1, 3, 1, 1, 1, 1),
(7, 3, 2, 3, 2, 1, 1, 1);
INSERT INTO acl_entry (acl_object_identity, ace_order, sid, mask, granting, audit_success, audit_failure) VALUES
(1, 1, 1, 1, 1, 1, 1),
(1, 2, 1, 2, 1, 1, 1),
(1, 3, 3, 1, 1, 1, 1),
(2, 1, 2, 1, 1, 1, 1),
(2, 2, 3, 1, 1, 1, 1),
(3, 1, 3, 1, 1, 1, 1),
(3, 2, 3, 2, 1, 1, 1);

View File

@ -4,10 +4,12 @@ import com.baeldung.acl.Application;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@DirtiesContext
public class SpringContextTest {
@Test

View File

@ -11,7 +11,8 @@
<parent>
<groupId>com.baeldung</groupId>
<artifactId>spring-security-modules</artifactId>
<artifactId>parent-boot-3</artifactId>
<relativePath>../../parent-boot-3</relativePath>
<version>0.0.1-SNAPSHOT</version>
</parent>
@ -30,7 +31,7 @@
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>
<!-- oauth2 -->
<dependency>

View File

@ -2,6 +2,7 @@ package com.baeldung.cognito;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@ -10,16 +11,13 @@ public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf()
.and()
.authorizeRequests(authz -> authz.mvcMatchers("/")
http.csrf(Customizer.withDefaults())
.authorizeHttpRequests(authz -> authz.requestMatchers("/")
.permitAll()
.anyRequest()
.authenticated())
.oauth2Login()
.and()
.logout()
.logoutSuccessUrl("/");
.oauth2Login(Customizer.withDefaults())
.logout(httpSecurityLogoutConfigurer -> httpSecurityLogoutConfigurer.logoutSuccessUrl("/"));
return http.build();
}
}

View File

@ -19,13 +19,13 @@ public class ExposeAttemptedPathAuthorizationAuditListener extends AbstractAutho
@Override
public void onApplicationEvent(AuthorizationEvent event) {
if (event instanceof AuthorizationDeniedEvent) {
onAuthorizationFailureEvent((AuthorizationDeniedEvent) event);
onAuthorizationFailureEvent(event);
}
}
private void onAuthorizationFailureEvent(AuthorizationDeniedEvent event) {
private void onAuthorizationFailureEvent(AuthorizationEvent event) {
String name = this.getName(event.getAuthentication());
Map<String, Object> data = new LinkedHashMap();
Map<String, Object> data = new LinkedHashMap<>();
Object details = this.getDetails(event.getAuthentication());
if (details != null) {
data.put("details", details);

View File

@ -3,9 +3,10 @@ package com.baeldung.app.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
@ -14,7 +15,7 @@ import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableMethodSecurity
public class WebSecurityConfig {
@Bean
@ -25,8 +26,8 @@ public class WebSecurityConfig {
.anyRequest()
.authenticated())
.httpBasic(Customizer.withDefaults())
.logout(logout -> logout.disable())
.csrf(csrf -> csrf.disable());
.logout(AbstractHttpConfigurer::disable)
.csrf(AbstractHttpConfigurer::disable);
return http.build();
}

View File

@ -6,9 +6,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("api/tasks")
@ -20,14 +21,14 @@ public class TaskController {
@Autowired(required = false)
private UserDetailsService userDetailsService;
@RequestMapping(method = RequestMethod.GET)
@GetMapping
public ResponseEntity<Iterable<Task>> findAllTasks() {
Iterable<Task> tasks = taskService.findAll();
return ResponseEntity.ok().body(tasks);
}
@RequestMapping(method = RequestMethod.POST, consumes = "application/json")
@PostMapping(consumes = "application/json")
public ResponseEntity<Iterable<Task>> addTasks(@RequestBody Iterable<Task> newTasks) {
Iterable<Task> tasks = taskService.save(newTasks);

View File

@ -14,7 +14,7 @@ public class CustomFilter implements Filter {
private static Logger LOGGER = LoggerFactory.getLogger(CustomFilter.class);
@Override
public void init(FilterConfig config) throws ServletException {
public void init(FilterConfig config) {
}
@Override

View File

@ -2,34 +2,31 @@ package com.baeldung.denyonmissing;
import static org.springframework.security.access.annotation.Jsr250SecurityConfig.DENY_ALL_ATTRIBUTE;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.MergedAnnotation;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.method.AbstractFallbackMethodSecurityMetadataSource;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
public class CustomPermissionAllowedMethodSecurityMetadataSource extends AbstractFallbackMethodSecurityMetadataSource {
@Override
protected Collection<ConfigAttribute> findAttributes(Class<?> clazz) {
return null;
}
@Component
public class CustomPermissionAllowedMethodSecurityMetadataSource implements AuthorizationManager<MethodInvocation> {
@Override
protected Collection<ConfigAttribute> findAttributes(Method method, Class<?> targetClass) {
MergedAnnotations annotations = MergedAnnotations.from(method,
MergedAnnotations.SearchStrategy.DIRECT);
public AuthorizationDecision check(Supplier<Authentication> authentication, MethodInvocation mi) {
MergedAnnotations annotations = MergedAnnotations.from(mi.getMethod(), MergedAnnotations.SearchStrategy.DIRECT);
List<ConfigAttribute> attributes = new ArrayList<>();
MergedAnnotations classAnnotations = MergedAnnotations.from(targetClass, MergedAnnotations.SearchStrategy.DIRECT);
MergedAnnotations classAnnotations = MergedAnnotations.from(DenyOnMissingController.class, MergedAnnotations.SearchStrategy.DIRECT);
// if the class is annotated as @Controller we should by default deny access to every method
if (classAnnotations.get(Controller.class).isPresent()) {
attributes.add(DENY_ALL_ATTRIBUTE);
@ -38,12 +35,6 @@ public class CustomPermissionAllowedMethodSecurityMetadataSource extends Abstrac
if (annotations.get(PreAuthorize.class).isPresent() || annotations.get(PostAuthorize.class).isPresent()) {
return null;
}
return attributes;
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
return new AuthorizationDecision(!Collections.disjoint(attributes, authentication.get().getAuthorities()));
}
}

View File

@ -1,10 +1,12 @@
package com.baeldung.denyonmissing;
import org.springframework.aop.Advisor;
import org.springframework.aop.support.JdkRegexpMethodPointcut;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.method.MethodSecurityMetadataSource;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
import org.springframework.security.authorization.method.AuthorizationInterceptorsOrder;
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
@ -12,11 +14,16 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class DenyMethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
return new CustomPermissionAllowedMethodSecurityMetadataSource();
@EnableMethodSecurity
public class DenyMethodSecurityConfig {
@Bean
public Advisor preAuthorize(CustomPermissionAllowedMethodSecurityMetadataSource manager) {
JdkRegexpMethodPointcut pattern = new JdkRegexpMethodPointcut();
pattern.setPattern("com.baeldung.denyonmissing.*");
AuthorizationManagerBeforeMethodInterceptor interceptor = new AuthorizationManagerBeforeMethodInterceptor(pattern, manager);
interceptor.setOrder(AuthorizationInterceptorsOrder.PRE_AUTHORIZE.getOrder() - 1);
return interceptor;
}
@Bean

View File

@ -6,6 +6,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@ -42,7 +43,7 @@ public class AppConfig implements WebMvcConfigurer {
.anyRequest()
.authenticated())
.httpBasic(Customizer.withDefaults())
.csrf(csrf -> csrf.disable());
.csrf(AbstractHttpConfigurer::disable);
return http.build();
}

View File

@ -6,11 +6,11 @@ import com.fasterxml.jackson.annotation.JsonView;
public class Item {
@JsonView(View.User.class)
private int id;
private final int id;
@JsonView(View.User.class)
private String name;
private final String name;
@JsonView(View.Admin.class)
private String ownerName;
private final String ownerName;
public Item(int id, String name, String ownerName) {
this.id = id;

View File

@ -41,10 +41,8 @@ public class DenyOnMissingControllerIntegrationTest {
@Test
@WithMockUser(username = "user")
public void givenANormalUser_whenCallingBye_thenAccessDenied() throws Exception {
ServletException exception = Assertions.assertThrows(ServletException.class, () -> {
mockMvc.perform(get("/bye"));
});
public void givenANormalUser_whenCallingBye_thenAccessDenied() {
ServletException exception = Assertions.assertThrows(ServletException.class, () -> mockMvc.perform(get("/bye")));
Assertions.assertNotNull(exception);
Assertions.assertEquals(exception.getCause().getClass(), AccessDeniedException.class);

View File

@ -15,7 +15,7 @@ import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -66,6 +66,6 @@ public class SpringSecurityJsonViewIntegrationTest {
});
Assertions.assertEquals(exception.getCause().getClass(), IllegalArgumentException.class);
assertTrue(exception.getCause().getMessage().equals("Ambiguous @JsonView declaration for roles ROLE_ADMIN,ROLE_USER"));
assertEquals("Ambiguous @JsonView declaration for roles ROLE_ADMIN,ROLE_USER", exception.getCause().getMessage());
}
}

View File

@ -1,6 +1,7 @@
package com.baeldung.methodsecurity;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
@ -50,7 +51,7 @@ public class MethodSecurityIntegrationTest {
@WithMockUser(username = "john", roles = { "EDITOR" })
public void givenUsernameJohn_whenCallIsValidUsername_thenReturnTrue() {
boolean isValid = userRoleService.isValidUsername("john");
assertEquals(true, isValid);
assertTrue(isValid);
}
@Test(expected = AccessDeniedException.class)
@ -60,7 +61,7 @@ public class MethodSecurityIntegrationTest {
}
@Test(expected = AccessDeniedException.class)
@WithMockUser(username = "john", roles = { "USER" })
@WithMockUser(username = "john")
public void givenRoleUser_whenCallGetUsername2_thenReturnAccessDenied() {
userRoleService.getUsername2();
}
@ -76,7 +77,7 @@ public class MethodSecurityIntegrationTest {
@WithMockUser(username = "john", roles = { "VIEWER" })
public void givenUsernameJerry_whenCallIsValidUsername2_thenReturnFalse() {
boolean isValid = userRoleService.isValidUsername2("jerry");
assertEquals(false, isValid);
assertFalse(isValid);
}
@Test