9

I have a Spring Boot application using JPA that has 2 datasources, 1 for DB2 and 1 for SQL Server.

When I try to save an entity to SQL Server, no error is thrown, but the entity is not persisted to the database. I do not see an insert being generated in the log.

Thanks in advance

Here is the code I execute to try and save the entity. @Component

public class TestSave { @Autowired private BeercupMessageLogRepository repository; @Scheduled(fixedRate = 500000) public void reportCurrentTime() { System.out.println("Testing Save ... "); // Save the message in the transaction log - TypeId = 1 for Quote BeercupMessageLog beercupMessage = new BeercupMessageLog(1,"THIS IS A TEST ...", false); beercupMessage = repository.save(beercupMessage); System.out.println("Testing save complete ...."); } } 

Here is the sql Server configuration.

@Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages="com.xxx.beverage.repository.sqlserver",entityManagerFactoryRef = "entityManagerFactory", transactionManagerRef = "transactionManager") public class sqlserverConfiguration { @Bean(name="datasource") @Primary @ConfigurationProperties(prefix = "sqlserver.datasource") public DataSource sqlserverDataSource() { return DataSourceBuilder.create().build(); } @PersistenceContext(unitName="primary") @Primary @Bean(name = "entityManagerFactory") public LocalContainerEntityManagerFactoryBean sqlserverEntityManagerFactory(EntityManagerFactoryBuilder builder) { return builder.dataSource(sqlserverDataSource()).persistenceUnit("sqlServer").properties(jpaProperties()) .packages("com.boelter.beverage.model.sqlserver").build(); } private Map<String, Object> jpaProperties() { Map<String, Object> props = new HashMap<>(); props.put("spring.jpa.hibernate.naming-strategy","org.hibernate.cfg.DefaultNamingStrategy"); props.put("hibernate.default_schema","dbo"); return props; } } 

Here is the SQL Server Repository

public interface BeercupMessageLogRepository extends

CrudRepository<BeercupMessageLog, Long> { BeercupMessageLog findOne(Long id); List<BeercupMessageLog> findByMessageTypeId(Long messageTypeId); List<BeercupMessageLog> findAll(); 

Here is the DB2 configuration.

@Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages="com.boelter.beverage.repository.db2",entityManagerFactoryRef = "entityManagerFactory 2", transactionManagerRef = "transactionManager2") public class db2Configuration { @Bean(name="db2DataSource") @ConfigurationProperties(prefix = "db2.datasource") public DataSource db2DataSource() { return DataSourceBuilder.create().build(); } @PersistenceContext(unitName="secondary") @Bean(name = "entityManagerFactory2") public LocalContainerEntityManagerFactoryBean db2EntityManagerFactory(EntityManagerFactoryBuilder builder) { return builder.dataSource(db2DataSource()).persistenceUnit("db2").properties(jpaProperties()) .packages("com.boelter.beverage.model.db2").build(); } private Map<String, Object> jpaProperties() { Map<String, Object> props = new HashMap<>(); props.put("spring.jpa.hibernate.naming-strategy","org.hibernate.cfg.DefaultNamingStrategy"); //props.put("spring.jpa.hibernate.naming-strategy","org.hibernate.cfg.ImprovedNamingStrategy"); //props.put("spring.jpa.properties.hibernate.default_schema","R3QASDATA"); //props.put("spring.jpa.show-sql","true"); return props; } } 

Here is the entity.

package com.boelter.beverage.model.sqlserver; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import org.springframework.transaction.annotation.Transactional; @Table (name="[BeercupMessageLog]") @Entity @Transactional public class BeercupMessageLog { @Id @GeneratedValue(strategy=GenerationType.AUTO) private long messageId; @Column(name="MessageTypeId", nullable = false) private long messageTypeId; @Column(name="Processed", nullable = false) private boolean processed; // Set updatable and insertable to false so JPA does not try to pass a value. The DB has a default // of the current date if no value is passed @Column(name="MessageDate", updatable=false, insertable=false) private Date messageDate; @Column(name="MessageText", nullable = false) private String messageText; protected BeercupMessageLog() {} public BeercupMessageLog(long messageTypeId, String messageText, boolean processed) { this.messageTypeId = messageTypeId; this.messageText = messageText; this.processed = processed; } /** * @return the messageId */ public long getMessageId() { return messageId; } /** * @param messageId the messageId to set */ public void setMessageId(long messageId) { this.messageId = messageId; } /** * @return the messageTypeId */ public long getMessageTypeId() { return messageTypeId; } /** * @param messageTypeId the messageTypeId to set */ public void setMessageTypeId(long messageTypeId) { this.messageTypeId = messageTypeId; } /** * @return the messageDate */ public Date getMessageDate() { return messageDate; } /** * @param messageDate the messageDate to set */ public void setMessageDate(Date messageDate) { this.messageDate = messageDate; } /** * @return the processed */ public boolean isProcessed() { return processed; } /** * @param processed the processed to set */ public void setProcessed(boolean processed) { this.processed = processed; } /** * @return the messageText */ public String getMessageText() { return messageText; } /** * @param messageText the messageText to set */ public void setMessageText(String messageText) { this.messageText = messageText; } @Override public String toString() { return String.format( "BeercupMessage[id=%d, typeId=%d, message='%s']", messageId, messageTypeId, messageText); } } 
2
  • can you add your entity to the question as well. Commented May 10, 2016 at 16:02
  • Yes, just added at the end ..... Commented May 13, 2016 at 12:42

3 Answers 3

10

I guess it's more your DB2 database which is not saved, because the problem is you need to set a custom transactionManagerRef for the database for which the datasource, entitymanager factory and transaction manager are not marked @Primary. Here you configured transactionManagerRef = "transactionManager2" but you did not inject it in the configuration bean.

Just add to db2Configuration something like :

@Bean(name = "transactionManager2") public PlatformTransactionManager accountTransactionManager(EntityManagerFactoryBuilder builder) { JpaTransactionManager tm = new JpaTransactionManager(); tm.setEntityManagerFactory(db2EntityManagerFactory(builder).getObject()); tm.setDataSource(db2DataSource()); return tm; } 
Sign up to request clarification or add additional context in comments.

3 Comments

This must be the accepted answer. I made a mistake like this, created the transactionManager bean but forget to add the transactionManagerRef on @EnableJpaRepositories annotation. The application was able to read the datasources registries, but unable to save new entities.
In my case, my problem is that I created PlatformTransactionManager bean by new DataSourceTransactionManager(getDataSource()), It seems BasicDataSourceTransactionManager just does not work well with spring jpa(I used spring boot2 starter which bring in spring-data-jpa:2.0.12 ). Replacing it by new JpaTransactionManager solved my problem
Didn't knew that two different TMs are required when connecting to different databases. This is really helpful.
3

I had the same problem, for me it was Spring Batch:

public class BatchConfiguration extends DefaultBatchConfigurer {

The fact that I extended DefaultBatchConfigurer was creating a second EntityManager and so my data source was not persisting the data into the DB.

2 Comments

Thanks for your sharing your resolution
I commented this out and it worked for me. Thanks for sharing.
1

Using org.springframework.batch.support.transaction.ResourcelessTransactionManager will also spoil the transactional database commit capability. So do not create ResourcelessTransactionManager as a bean.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.