Skip to content

Commit 50c2f1f

Browse files
BAEL-8326 - Guide to @DynamicInsert in Spring Data JPA (#17436)
1 parent ffd082d commit 50c2f1f

File tree

4 files changed

+202
-0
lines changed

4 files changed

+202
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.baeldung.hibernate.dynamicinsert;
2+
3+
import org.springframework.data.jpa.repository.JpaRepository;
4+
import org.springframework.stereotype.Repository;
5+
6+
import com.baeldung.hibernate.dynamicinsert.model.Account;
7+
8+
@Repository
9+
public interface AccountRepository extends JpaRepository<Account, Integer> {
10+
11+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package com.baeldung.hibernate.dynamicinsert;
2+
3+
import java.util.Properties;
4+
5+
import jakarta.persistence.EntityManagerFactory;
6+
7+
import javax.sql.DataSource;
8+
9+
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
10+
import org.springframework.beans.factory.annotation.Autowired;
11+
import org.springframework.context.annotation.Bean;
12+
import org.springframework.context.annotation.ComponentScan;
13+
import org.springframework.context.annotation.Configuration;
14+
import org.springframework.context.annotation.PropertySource;
15+
import org.springframework.core.env.Environment;
16+
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
17+
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
18+
import org.springframework.orm.jpa.JpaTransactionManager;
19+
import org.springframework.orm.jpa.JpaVendorAdapter;
20+
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
21+
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
22+
import org.springframework.transaction.PlatformTransactionManager;
23+
import org.springframework.transaction.annotation.EnableTransactionManagement;
24+
25+
import com.google.common.base.Preconditions;
26+
27+
@EnableTransactionManagement
28+
@Configuration
29+
@PropertySource({ "classpath:persistence-h2.properties" })
30+
@EnableJpaRepositories(basePackages = { "com.baeldung.hibernate.dynamicinsert" })
31+
@ComponentScan({ "com.baeldung.hibernate.dynamicinsert" })
32+
public class DynamicInsertConfig {
33+
34+
@Autowired
35+
private Environment env;
36+
37+
@Bean
38+
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
39+
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
40+
em.setDataSource(dataSource());
41+
em.setPackagesToScan(new String[] { "com.baeldung.hibernate.dynamicinsert.model" });
42+
43+
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
44+
em.setJpaVendorAdapter(vendorAdapter);
45+
em.setJpaProperties(additionalProperties());
46+
47+
return em;
48+
}
49+
50+
@Bean
51+
public DataSource dataSource() {
52+
final BasicDataSource dataSource = new BasicDataSource();
53+
dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
54+
dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
55+
dataSource.setUsername(env.getProperty("jdbc.user"));
56+
dataSource.setPassword(env.getProperty("jdbc.pass"));
57+
58+
return dataSource;
59+
}
60+
61+
@Bean
62+
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
63+
JpaTransactionManager transactionManager = new JpaTransactionManager();
64+
transactionManager.setEntityManagerFactory(emf);
65+
66+
return transactionManager;
67+
}
68+
69+
@Bean
70+
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
71+
return new PersistenceExceptionTranslationPostProcessor();
72+
}
73+
74+
Properties additionalProperties() {
75+
Properties properties = new Properties();
76+
properties.setProperty("hibernate.hbm2ddl.auto", Preconditions.checkNotNull(env.getProperty("hibernate.hbm2ddl.auto")));
77+
properties.setProperty("hibernate.dialect", Preconditions.checkNotNull(env.getProperty("hibernate.dialect")));
78+
properties.setProperty("hibernate.show_sql", "false");
79+
return properties;
80+
}
81+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.baeldung.hibernate.dynamicinsert.model;
2+
3+
import jakarta.persistence.Column;
4+
import jakarta.persistence.Entity;
5+
import jakarta.persistence.Id;
6+
7+
import org.hibernate.annotations.DynamicInsert;
8+
9+
@Entity
10+
@DynamicInsert
11+
public class Account {
12+
13+
@Id
14+
private int id;
15+
16+
@Column
17+
private String name;
18+
19+
@Column
20+
private String type;
21+
22+
@Column
23+
private boolean active;
24+
25+
@Column
26+
private String description;
27+
28+
public Account() {
29+
}
30+
31+
public int getId() {
32+
return id;
33+
}
34+
35+
public void setId(int id) {
36+
this.id = id;
37+
}
38+
39+
public String getName() {
40+
return name;
41+
}
42+
43+
public void setName(String name) {
44+
this.name = name;
45+
}
46+
47+
public String getType() {
48+
return type;
49+
}
50+
51+
public void setType(String type) {
52+
this.type = type;
53+
}
54+
55+
public boolean isActive() {
56+
return active;
57+
}
58+
59+
public void setActive(boolean active) {
60+
this.active = active;
61+
}
62+
63+
public String getDescription() {
64+
return description;
65+
}
66+
67+
public void setDescription(String description) {
68+
this.description = description;
69+
}
70+
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.baeldung.hibernate.dynamicinsert;
2+
3+
import jakarta.transaction.Transactional;
4+
5+
import org.junit.jupiter.api.MethodOrderer;
6+
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.api.TestMethodOrder;
8+
import org.junit.jupiter.api.extension.ExtendWith;
9+
import org.springframework.beans.factory.annotation.Autowired;
10+
import org.springframework.test.annotation.Commit;
11+
import org.springframework.test.context.ContextConfiguration;
12+
import org.springframework.test.context.junit.jupiter.SpringExtension;
13+
import org.springframework.test.context.support.AnnotationConfigContextLoader;
14+
15+
import com.baeldung.hibernate.dynamicinsert.model.Account;
16+
17+
@ExtendWith(SpringExtension.class)
18+
@ContextConfiguration(classes = { DynamicInsertConfig.class }, loader = AnnotationConfigContextLoader.class)
19+
@Transactional
20+
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
21+
class DynamicInsertIntegrationTest {
22+
23+
private static final Integer ACCOUNT_ID = 1;
24+
25+
@Autowired
26+
private AccountRepository accountRepository;
27+
28+
@Test
29+
@Commit
30+
// Enable Hibernate's debug logging in logback.xml to see the generated SQL statement.
31+
void givenEntityWithDynamicInsert_whenSavingEntity_thenOnlyNotNullFieldsAreInserted() {
32+
Account account = new Account();
33+
account.setId(ACCOUNT_ID);
34+
account.setName("account1");
35+
account.setActive(true);
36+
accountRepository.save(account);
37+
}
38+
39+
}

0 commit comments

Comments
 (0)