Merge remote-tracking branch 'upstream/master' into JAVA-2305
This commit is contained in:
+49
@@ -0,0 +1,49 @@
|
||||
package com.baeldung.jdbcmetadata;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class DatabaseConfig {
|
||||
private static final Logger LOG = Logger.getLogger(DatabaseConfig.class);
|
||||
|
||||
private Connection connection;
|
||||
|
||||
public DatabaseConfig() {
|
||||
try {
|
||||
Class.forName("org.h2.Driver");
|
||||
String url = "jdbc:h2:mem:testdb";
|
||||
connection = DriverManager.getConnection(url, "sa", "");
|
||||
} catch (ClassNotFoundException | SQLException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Connection getConnection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
createTables();
|
||||
createViews();
|
||||
}
|
||||
|
||||
private void createTables() {
|
||||
try {
|
||||
connection.createStatement().executeUpdate("create table CUSTOMER (ID int primary key auto_increment, NAME VARCHAR(45))");
|
||||
connection.createStatement().executeUpdate("create table CUST_ADDRESS (ID VARCHAR(36), CUST_ID int, ADDRESS VARCHAR(45), FOREIGN KEY (CUST_ID) REFERENCES CUSTOMER(ID))");
|
||||
} catch (SQLException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void createViews() {
|
||||
try {
|
||||
connection.createStatement().executeUpdate("CREATE VIEW CUSTOMER_VIEW AS SELECT * FROM CUSTOMER");
|
||||
} catch (SQLException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.baeldung.jdbcmetadata;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class JdbcMetadataApplication {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(JdbcMetadataApplication.class);
|
||||
|
||||
public static void main(String[] args) {
|
||||
DatabaseConfig databaseConfig = new DatabaseConfig();
|
||||
databaseConfig.init();
|
||||
try {
|
||||
MetadataExtractor metadataExtractor = new MetadataExtractor(databaseConfig.getConnection());
|
||||
metadataExtractor.extractTableInfo();
|
||||
metadataExtractor.extractSystemTables();
|
||||
metadataExtractor.extractViews();
|
||||
String tableName = "CUSTOMER";
|
||||
metadataExtractor.extractColumnInfo(tableName);
|
||||
metadataExtractor.extractPrimaryKeys(tableName);
|
||||
metadataExtractor.extractForeignKeys("CUST_ADDRESS");
|
||||
metadataExtractor.extractDatabaseInfo();
|
||||
metadataExtractor.extractUserName();
|
||||
metadataExtractor.extractSupportedFeatures();
|
||||
} catch (SQLException e) {
|
||||
LOG.error("Error while executing SQL statements", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
package com.baeldung.jdbcmetadata;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class MetadataExtractor {
|
||||
private final DatabaseMetaData databaseMetaData;
|
||||
|
||||
public MetadataExtractor(Connection connection) throws SQLException {
|
||||
this.databaseMetaData = connection.getMetaData();
|
||||
DatabaseMetaData databaseMetaData = connection.getMetaData();
|
||||
}
|
||||
|
||||
public void extractTableInfo() throws SQLException {
|
||||
ResultSet resultSet = databaseMetaData.getTables(null, null, "CUST%", new String[] { "TABLE" });
|
||||
while (resultSet.next()) {
|
||||
// Print the names of existing tables
|
||||
System.out.println(resultSet.getString("TABLE_NAME"));
|
||||
System.out.println(resultSet.getString("REMARKS"));
|
||||
}
|
||||
}
|
||||
|
||||
public void extractSystemTables() throws SQLException {
|
||||
ResultSet resultSet = databaseMetaData.getTables(null, null, null, new String[] { "SYSTEM TABLE" });
|
||||
while (resultSet.next()) {
|
||||
// Print the names of system tables
|
||||
System.out.println(resultSet.getString("TABLE_NAME"));
|
||||
}
|
||||
}
|
||||
|
||||
public void extractViews() throws SQLException {
|
||||
ResultSet resultSet = databaseMetaData.getTables(null, null, null, new String[] { "VIEW" });
|
||||
while (resultSet.next()) {
|
||||
// Print the names of existing views
|
||||
System.out.println(resultSet.getString("TABLE_NAME"));
|
||||
}
|
||||
}
|
||||
|
||||
public void extractColumnInfo(String tableName) throws SQLException {
|
||||
ResultSet columns = databaseMetaData.getColumns(null, null, tableName, null);
|
||||
|
||||
while (columns.next()) {
|
||||
String columnName = columns.getString("COLUMN_NAME");
|
||||
String columnSize = columns.getString("COLUMN_SIZE");
|
||||
String datatype = columns.getString("DATA_TYPE");
|
||||
String isNullable = columns.getString("IS_NULLABLE");
|
||||
String isAutoIncrement = columns.getString("IS_AUTOINCREMENT");
|
||||
System.out.println(String.format("ColumnName: %s, columnSize: %s, datatype: %s, isColumnNullable: %s, isAutoIncrementEnabled: %s", columnName, columnSize, datatype, isNullable, isAutoIncrement));
|
||||
}
|
||||
}
|
||||
|
||||
public void extractPrimaryKeys(String tableName) throws SQLException {
|
||||
ResultSet primaryKeys = databaseMetaData.getPrimaryKeys(null, null, tableName);
|
||||
while (primaryKeys.next()) {
|
||||
String primaryKeyColumnName = primaryKeys.getString("COLUMN_NAME");
|
||||
String primaryKeyName = primaryKeys.getString("PK_NAME");
|
||||
System.out.println(String.format("columnName:%s, pkName:%s", primaryKeyColumnName, primaryKeyName));
|
||||
}
|
||||
}
|
||||
|
||||
public void fun() throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
public void extractForeignKeys(String tableName) throws SQLException {
|
||||
ResultSet foreignKeys = databaseMetaData.getImportedKeys(null, null, tableName);
|
||||
while (foreignKeys.next()) {
|
||||
String pkTableName = foreignKeys.getString("PKTABLE_NAME");
|
||||
String fkTableName = foreignKeys.getString("FKTABLE_NAME");
|
||||
String pkColumnName = foreignKeys.getString("PKCOLUMN_NAME");
|
||||
String fkColumnName = foreignKeys.getString("FKCOLUMN_NAME");
|
||||
System.out.println(String.format("pkTableName:%s, fkTableName:%s, pkColumnName:%s, fkColumnName:%s", pkTableName, fkTableName, pkColumnName, fkColumnName));
|
||||
}
|
||||
}
|
||||
|
||||
public void extractDatabaseInfo() throws SQLException {
|
||||
String productName = databaseMetaData.getDatabaseProductName();
|
||||
String productVersion = databaseMetaData.getDatabaseProductVersion();
|
||||
|
||||
String driverName = databaseMetaData.getDriverName();
|
||||
String driverVersion = databaseMetaData.getDriverVersion();
|
||||
|
||||
System.out.println(String.format("Product name:%s, Product version:%s", productName, productVersion));
|
||||
System.out.println(String.format("Driver name:%s, Driver Version:%s", driverName, driverVersion));
|
||||
}
|
||||
|
||||
public void extractUserName() throws SQLException {
|
||||
String userName = databaseMetaData.getUserName();
|
||||
System.out.println(userName);
|
||||
ResultSet schemas = databaseMetaData.getSchemas();
|
||||
while (schemas.next()) {
|
||||
String table_schem = schemas.getString("TABLE_SCHEM");
|
||||
String table_catalog = schemas.getString("TABLE_CATALOG");
|
||||
System.out.println(String.format("Table_schema:%s, Table_catalog:%s", table_schem, table_catalog));
|
||||
}
|
||||
}
|
||||
|
||||
public void extractSupportedFeatures() throws SQLException {
|
||||
System.out.println("Supports scrollable & Updatable Result Set: " + databaseMetaData.supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE));
|
||||
System.out.println("Supports Full Outer Joins: " + databaseMetaData.supportsFullOuterJoins());
|
||||
System.out.println("Supports Stored Procedures: " + databaseMetaData.supportsStoredProcedures());
|
||||
System.out.println("Supports Subqueries in 'EXISTS': " + databaseMetaData.supportsSubqueriesInExists());
|
||||
System.out.println("Supports Transactions: " + databaseMetaData.supportsTransactions());
|
||||
System.out.println("Supports Core SQL Grammar: " + databaseMetaData.supportsCoreSQLGrammar());
|
||||
System.out.println("Supports Batch Updates: " + databaseMetaData.supportsBatchUpdates());
|
||||
System.out.println("Supports Column Aliasing: " + databaseMetaData.supportsColumnAliasing());
|
||||
System.out.println("Supports Savepoints: " + databaseMetaData.supportsSavepoints());
|
||||
System.out.println("Supports Union All: " + databaseMetaData.supportsUnionAll());
|
||||
System.out.println("Supports Union: " + databaseMetaData.supportsUnion());
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package com.baeldung.hibernate.hilo;
|
||||
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
import org.hibernate.annotations.Parameter;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class RestaurantOrder {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "hilo_sequence_generator")
|
||||
@GenericGenerator(
|
||||
name = "hilo_sequence_generator",
|
||||
strategy = "sequence",
|
||||
parameters = {
|
||||
@Parameter(name = "sequence_name", value = "hilo_seqeunce"),
|
||||
@Parameter(name = "initial_value", value = "1"),
|
||||
@Parameter(name = "increment_size", value = "3"),
|
||||
@Parameter(name = "optimizer", value = "hilo")
|
||||
}
|
||||
)
|
||||
private Long id;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
package com.baeldung.hibernate.hilo;
|
||||
|
||||
import org.apache.log4j.BasicConfigurator;
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.boot.Metadata;
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.SessionFactoryBuilder;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class HibernateHiloUnitTest {
|
||||
private Session session;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
try {
|
||||
configureLogger();
|
||||
|
||||
ServiceRegistry serviceRegistry = configureServiceRegistry();
|
||||
SessionFactory factory = getSessionFactoryBuilder(serviceRegistry).build();
|
||||
session = factory.openSession();
|
||||
} catch (HibernateException | IOException e) {
|
||||
fail("Failed to initiate Hibernate Session [Exception:" + e.toString() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
private void configureLogger() {
|
||||
BasicConfigurator.configure();
|
||||
LogManager.getLogger("org.hibernate").setLevel(Level.ERROR);
|
||||
LogManager.getLogger("org.hibernate.id.enhanced.SequenceStructure").setLevel(Level.DEBUG);
|
||||
LogManager.getLogger("org.hibernate.event.internal.AbstractSaveEventListener").setLevel(Level.DEBUG);
|
||||
LogManager.getLogger("org.hibernate.SQL").setLevel(Level.DEBUG);
|
||||
}
|
||||
|
||||
|
||||
private static SessionFactoryBuilder getSessionFactoryBuilder(ServiceRegistry serviceRegistry) {
|
||||
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
|
||||
metadataSources.addAnnotatedClass(RestaurantOrder.class);
|
||||
Metadata metadata = metadataSources.buildMetadata();
|
||||
|
||||
return metadata.getSessionFactoryBuilder();
|
||||
}
|
||||
|
||||
private static ServiceRegistry configureServiceRegistry() throws IOException {
|
||||
Properties properties = getProperties();
|
||||
|
||||
return new StandardServiceRegistryBuilder().applySettings(properties)
|
||||
.build();
|
||||
}
|
||||
|
||||
private static Properties getProperties() throws IOException {
|
||||
Properties properties = new Properties();
|
||||
URL propertiesURL = getPropertiesURL();
|
||||
|
||||
try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) {
|
||||
properties.load(inputStream);
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
private static URL getPropertiesURL() {
|
||||
return Thread.currentThread()
|
||||
.getContextClassLoader()
|
||||
.getResource("hibernate-hilo.properties");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenHiLoAlgorithm_when9EntitiesArePersisted_Then3callsToDBForNextValueShouldBeMade() {
|
||||
Transaction transaction = session.beginTransaction();
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
session.persist(new RestaurantOrder());
|
||||
session.flush();
|
||||
}
|
||||
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
hibernate.connection.driver_class=org.h2.Driver
|
||||
hibernate.connection.url=jdbc:h2:mem:hilo_db;DB_CLOSE_DELAY=-1
|
||||
hibernate.connection.username=sa
|
||||
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
||||
hibernate.show_sql=true
|
||||
hibernate.hbm2ddl.auto=create-drop
|
||||
hibernate.c3p0.min_size=5
|
||||
hibernate.c3p0.max_size=20
|
||||
hibernate.c3p0.acquire_increment=5
|
||||
hibernate.c3p0.timeout=1800
|
||||
@@ -0,0 +1,3 @@
|
||||
## JPA in Java
|
||||
|
||||
This module contains articles about the Java Persistence API (JPA) in Java.
|
||||
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>java-jpa-3</artifactId>
|
||||
<name>java-jpa-3</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>persistence-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<version>${hibernate.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-jpamodelgen</artifactId>
|
||||
<version>${hibernate.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>${h2.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--Compile time JPA API -->
|
||||
<dependency>
|
||||
<groupId>javax.persistence</groupId>
|
||||
<artifactId>javax.persistence-api</artifactId>
|
||||
<version>${javax.persistence-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--Runtime JPA implementation -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>eclipselink</artifactId>
|
||||
<version>${eclipselink.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>${postgres.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<compilerArgument>-proc:none</compilerArgument>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<hibernate.version>5.4.14.Final</hibernate.version>
|
||||
<eclipselink.version>2.7.4</eclipselink.version>
|
||||
<postgres.version>42.2.5</postgres.version>
|
||||
<javax.persistence-api.version>2.2</javax.persistence-api.version>
|
||||
<assertj.version>3.11.1</assertj.version>
|
||||
<maven-compiler-plugin.version>3.5.1</maven-compiler-plugin.version>
|
||||
<maven-processor-plugin.version>3.3.3</maven-processor-plugin.version>
|
||||
<build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package com.baeldung.jpa.equality;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
public class EqualByBusinessKey {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String email;
|
||||
|
||||
public EqualByBusinessKey() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return java.util.Objects.hashCode(email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj instanceof EqualByBusinessKey) {
|
||||
if (((EqualByBusinessKey) obj).getEmail() == getEmail()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.baeldung.jpa.equality;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
public class EqualById {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String email;
|
||||
|
||||
public EqualById() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((id == null) ? 0 : id.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj instanceof EqualById) {
|
||||
return ((EqualById) obj).getId().equals(getId());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.baeldung.jpa.equality;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
public class EqualByJavaDefault implements Cloneable{
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String email;
|
||||
|
||||
public EqualByJavaDefault() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
|
||||
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
|
||||
version="2.2">
|
||||
<persistence-unit name="jpa-h2-equality">
|
||||
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||
<class>com.baeldung.jpa.equality.EqualByJavaDefault</class>
|
||||
<class>com.baeldung.jpa.equality.EqualById</class>
|
||||
<class>com.baeldung.jpa.equality.EqualByBusinessKey</class>
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
<properties>
|
||||
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
|
||||
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test" />
|
||||
<property name="javax.persistence.jdbc.user" value="sa" />
|
||||
<property name="javax.persistence.jdbc.password" value="" />
|
||||
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
|
||||
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
|
||||
<property name="show_sql" value="false" />
|
||||
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false" />
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
</persistence>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT"
|
||||
class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -
|
||||
%msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package com.baeldung.jpa.equality;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Persistence;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class EqualityUnitTest {
|
||||
|
||||
private static EntityManagerFactory factory;
|
||||
private static EntityManager entityManager;
|
||||
|
||||
@BeforeClass
|
||||
public static void setup() {
|
||||
factory = Persistence.createEntityManagerFactory("jpa-h2-equality");
|
||||
entityManager = factory.createEntityManager();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenObjectBasedEquality_whenUsingEquals_thenEqualIsBasedOnInstance() throws CloneNotSupportedException {
|
||||
EqualByJavaDefault object1 = new EqualByJavaDefault();
|
||||
EqualByJavaDefault object2 = new EqualByJavaDefault();
|
||||
|
||||
object1.setEmail("test.user@domain.com");
|
||||
|
||||
entityManager.getTransaction().begin();
|
||||
entityManager.persist(object1);
|
||||
entityManager.getTransaction().commit();
|
||||
|
||||
object2 = (EqualByJavaDefault) object1.clone();
|
||||
|
||||
Assert.assertNotEquals(object1, object2);
|
||||
Assert.assertEquals(object1.getId(), object2.getId());
|
||||
Assert.assertEquals(object1.getEmail(), object2.getEmail());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIdBasedEquality_whenUsingEquals_thenEqualIsBasedOnId() {
|
||||
EqualById object1 = new EqualById();
|
||||
EqualById object2 = new EqualById();
|
||||
|
||||
object1.setEmail("test.user.1@domain.com");
|
||||
object2.setEmail("test.user.2@domain.com");
|
||||
|
||||
entityManager.getTransaction().begin();
|
||||
entityManager.persist(object1);
|
||||
entityManager.getTransaction().commit();
|
||||
|
||||
object2.setId(object1.getId());
|
||||
|
||||
Assert.assertEquals(object1, object2);
|
||||
Assert.assertEquals(object1.getId(), object2.getId());
|
||||
Assert.assertNotEquals(object1.getEmail(), object2.getEmail());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenBusinessKeyBasedEquality_whenUsingEquals_thenEqualIsBasedOnBusinessKey() {
|
||||
EqualByBusinessKey object1 = new EqualByBusinessKey();
|
||||
EqualByBusinessKey object2 = new EqualByBusinessKey();
|
||||
|
||||
object1.setEmail("test.user@test-domain.com");
|
||||
object2.setEmail("test.user@test-domain.com");
|
||||
|
||||
entityManager.getTransaction().begin();
|
||||
entityManager.persist(object1);
|
||||
entityManager.getTransaction().commit();
|
||||
|
||||
Assert.assertEquals(object1, object2);
|
||||
Assert.assertNotEquals(object1.getId(), object2.getId());
|
||||
}
|
||||
}
|
||||
@@ -19,12 +19,14 @@
|
||||
<module>core-java-persistence</module>
|
||||
<module>deltaspike</module>
|
||||
<module>elasticsearch</module>
|
||||
<module>flyway</module>
|
||||
<module>flyway-repair</module>
|
||||
<module>hbase</module>
|
||||
<module>hibernate5</module>
|
||||
<module>hibernate-mapping</module> <!-- long running -->
|
||||
<module>hibernate-ogm</module>
|
||||
<module>hibernate-annotations</module>
|
||||
<module>hibernate-exceptions</module>
|
||||
<module>hibernate-libraries</module>
|
||||
<module>hibernate-jpa</module>
|
||||
<module>hibernate-queries</module>
|
||||
@@ -53,6 +55,7 @@
|
||||
<module>spring-boot-persistence-mongodb</module>
|
||||
<module>spring-data-cassandra</module>
|
||||
<module>spring-data-cassandra-reactive</module>
|
||||
<module>spring-data-cosmosdb</module>
|
||||
<module>spring-data-couchbase-2</module>
|
||||
<module>spring-data-dynamodb</module>
|
||||
<module>spring-data-eclipselink</module>
|
||||
@@ -78,6 +81,7 @@
|
||||
<module>spring-hibernate-5</module> <!-- long running -->
|
||||
<module>spring-hibernate4</module>
|
||||
<module>spring-jpa</module>
|
||||
<module>spring-jpa-2</module>
|
||||
<!-- <module>spring-mybatis</module> --> <!-- needs fixing in BAEL-9021 -->
|
||||
<module>spring-persistence-simple</module>
|
||||
<module>spring-persistence-simple-2</module>
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-data-cosmosdb</artifactId>
|
||||
<name>spring-data-cosmos-db</name>
|
||||
<description>tutorial for spring-data-cosmosdb</description>
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<cosmodb.version>2.3.0</cosmodb.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.azure</groupId>
|
||||
<artifactId>spring-data-cosmosdb</artifactId>
|
||||
<version>${cosmodb.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.baeldung.spring.data.cosmosdb;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class AzureCosmosDbApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AzureCosmosDbApplication.class, args);
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.baeldung.spring.data.cosmosdb.config;
|
||||
|
||||
import com.azure.data.cosmos.CosmosKeyCredential;
|
||||
import com.microsoft.azure.spring.data.cosmosdb.config.AbstractCosmosConfiguration;
|
||||
import com.microsoft.azure.spring.data.cosmosdb.config.CosmosDBConfig;
|
||||
import com.microsoft.azure.spring.data.cosmosdb.repository.config.EnableCosmosRepositories;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableCosmosRepositories(basePackages = "com.baeldung.spring.data.cosmosdb.repository")
|
||||
public class AzureCosmosDbConfiguration extends AbstractCosmosConfiguration {
|
||||
|
||||
@Value("${azure.cosmosdb.uri}")
|
||||
private String uri;
|
||||
|
||||
@Value("${azure.cosmosdb.key}")
|
||||
private String key;
|
||||
|
||||
@Value("${azure.cosmosdb.secondaryKey}")
|
||||
private String secondaryKey;
|
||||
|
||||
@Value("${azure.cosmosdb.database}")
|
||||
private String dbName;
|
||||
|
||||
private CosmosKeyCredential cosmosKeyCredential;
|
||||
|
||||
@Bean
|
||||
public CosmosDBConfig getConfig() {
|
||||
this.cosmosKeyCredential = new CosmosKeyCredential(key);
|
||||
CosmosDBConfig cosmosdbConfig = CosmosDBConfig.builder(uri, this.cosmosKeyCredential, dbName)
|
||||
.build();
|
||||
return cosmosdbConfig;
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package com.baeldung.spring.data.cosmosdb.controller;
|
||||
|
||||
import com.baeldung.spring.data.cosmosdb.entity.Product;
|
||||
import com.baeldung.spring.data.cosmosdb.service.ProductService;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/products")
|
||||
public class ProductController {
|
||||
|
||||
private ProductService productService;
|
||||
|
||||
@Autowired
|
||||
public ProductController(ProductService productService) {
|
||||
this.productService = productService;
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
public void create(@RequestBody Product product) {
|
||||
productService.saveProduct(product);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/{id}/category/{category}")
|
||||
public Optional<Product> get(@PathVariable String id, @PathVariable String category) {
|
||||
return productService.findById(id, category);
|
||||
}
|
||||
|
||||
@DeleteMapping(value = "/{id}/category/{category}")
|
||||
public void delete(@PathVariable String id, @PathVariable String category) {
|
||||
productService.delete(id, category);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public List<Product> getByName(@RequestParam String name) {
|
||||
return productService.findProductByName(name);
|
||||
}
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.baeldung.spring.data.cosmosdb.entity;
|
||||
|
||||
import com.microsoft.azure.spring.data.cosmosdb.core.mapping.Document;
|
||||
import com.microsoft.azure.spring.data.cosmosdb.core.mapping.PartitionKey;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Document(collection = "products")
|
||||
public class Product {
|
||||
|
||||
@Id
|
||||
private String productid;
|
||||
|
||||
private String productName;
|
||||
|
||||
private double price;
|
||||
|
||||
@PartitionKey
|
||||
private String productCategory;
|
||||
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.spring.data.cosmosdb.repository;
|
||||
|
||||
import com.baeldung.spring.data.cosmosdb.entity.Product;
|
||||
import com.microsoft.azure.spring.data.cosmosdb.repository.CosmosRepository;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface ProductRepository extends CosmosRepository<Product, String> {
|
||||
List<Product> findByProductName(String productName);
|
||||
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.baeldung.spring.data.cosmosdb.service;
|
||||
|
||||
import com.azure.data.cosmos.PartitionKey;
|
||||
import com.baeldung.spring.data.cosmosdb.entity.Product;
|
||||
import com.baeldung.spring.data.cosmosdb.repository.ProductRepository;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
public class ProductService {
|
||||
|
||||
private ProductRepository repository;
|
||||
|
||||
@Autowired
|
||||
public ProductService(ProductRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public List<Product> findProductByName(String productName) {
|
||||
return repository.findByProductName(productName);
|
||||
}
|
||||
|
||||
public Optional<Product> findById(String productId, String category) {
|
||||
return repository.findById(productId, new PartitionKey(category));
|
||||
}
|
||||
|
||||
public void saveProduct(Product product) {
|
||||
repository.save(product);
|
||||
}
|
||||
|
||||
public void delete(String productId, String category) {
|
||||
repository.deleteById(productId, new PartitionKey(category));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
azure.cosmosdb.uri=cosmodb-uri
|
||||
azure.cosmosdb.key=cosmodb-primary-key
|
||||
azure.cosmosdb.secondaryKey=cosmodb-second-key
|
||||
azure.cosmosdb.database=cosmodb-name
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.baeldung.spring.data.cosmosdb;
|
||||
|
||||
import com.azure.data.cosmos.PartitionKey;
|
||||
import com.baeldung.spring.data.cosmosdb.entity.Product;
|
||||
import com.baeldung.spring.data.cosmosdb.repository.ProductRepository;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@SpringBootTest
|
||||
public class AzureCosmosDbApplicationManualTest {
|
||||
|
||||
@Autowired
|
||||
ProductRepository productRepository;
|
||||
|
||||
@Test
|
||||
public void givenProductIsCreated_whenCallFindById_thenProductIsFound() {
|
||||
Product product = new Product();
|
||||
product.setProductid("1001");
|
||||
product.setProductCategory("Shirt");
|
||||
product.setPrice(110.0);
|
||||
product.setProductName("Blue Shirt");
|
||||
|
||||
productRepository.save(product);
|
||||
Product retrievedProduct = productRepository.findById("1001", new PartitionKey("Shirt"))
|
||||
.orElse(null);
|
||||
Assert.notNull(retrievedProduct, "Retrieved Product is Null");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,7 +6,6 @@
|
||||
- [Guide to Elasticsearch in Java](https://www.baeldung.com/elasticsearch-java)
|
||||
- [Geospatial Support in ElasticSearch](https://www.baeldung.com/elasticsearch-geo-spatial)
|
||||
- [A Simple Tagging Implementation with Elasticsearch](https://www.baeldung.com/elasticsearch-tagging)
|
||||
- [Introduction to Spring Data Elasticsearch (evaluation)](https://www.baeldung.com/spring-data-elasticsearch-test-2)
|
||||
|
||||
### Build the Project with Tests Running
|
||||
```
|
||||
|
||||
+2
-2
@@ -6,8 +6,8 @@ import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableJpaRepositories("com.baeldung")
|
||||
@EntityScan("com.baeldung")
|
||||
@EnableJpaRepositories("com.baeldung.boot")
|
||||
@EntityScan("com.baeldung.boot")
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import javax.persistence.*;
|
||||
import java.util.Set;
|
||||
|
||||
@Entity
|
||||
@Table(name = "users")
|
||||
@Table(name = "basic_users")
|
||||
public class BasicUser {
|
||||
|
||||
@Id
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
*.class
|
||||
|
||||
#folders#
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
@@ -0,0 +1,5 @@
|
||||
## Spring JPA (2)
|
||||
|
||||
### Relevant Articles:
|
||||
- [Many-To-Many Relationship in JPA](https://www.baeldung.com/jpa-many-to-many)
|
||||
- More articles: [[<-- prev]](/spring-jpa)
|
||||
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-jpa-2</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<name>spring-jpa-2</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>persistence-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- persistence -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
<version>${hibernate.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>${h2.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- test scoped -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<!-- Spring -->
|
||||
<org.springframework.version>5.1.5.RELEASE</org.springframework.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+1
-1
@@ -16,7 +16,7 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||
|
||||
@Configuration
|
||||
@PropertySource("classpath:/manytomany/test.properties")
|
||||
@PropertySource("manytomany/test.properties")
|
||||
public class ManyToManyTestConfiguration {
|
||||
|
||||
@Bean
|
||||
@@ -0,0 +1,13 @@
|
||||
*.class
|
||||
|
||||
#folders#
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
@@ -1,7 +1,4 @@
|
||||
=========
|
||||
|
||||
## Spring JPA Example Project
|
||||
|
||||
## Spring JPA (1)
|
||||
|
||||
### Relevant Articles:
|
||||
- [The DAO with JPA and Spring](https://www.baeldung.com/spring-dao-jpa)
|
||||
@@ -10,9 +7,7 @@
|
||||
- [Self-Contained Testing Using an In-Memory Database](https://www.baeldung.com/spring-jpa-test-in-memory-database)
|
||||
- [A Guide to Spring AbstractRoutingDatasource](https://www.baeldung.com/spring-abstract-routing-data-source)
|
||||
- [Obtaining Auto-generated Keys in Spring JDBC](https://www.baeldung.com/spring-jdbc-autogenerated-keys)
|
||||
- [Many-To-Many Relationship in JPA](https://www.baeldung.com/jpa-many-to-many)
|
||||
- [Spring Persistence (Hibernate and JPA) with a JNDI datasource](https://www.baeldung.com/spring-persistence-hibernate-and-jpa-with-a-jndi-datasource-2)
|
||||
|
||||
- More articles: [[next -->]](/spring-jpa-2)
|
||||
|
||||
### Eclipse Config
|
||||
After importing the project into Eclipse, you may see the following error:
|
||||
|
||||
Reference in New Issue
Block a user