Hello,
I'm using Spring Data JPA in a simple "frontend <=> service <=> repository" layered architecture.
What I'd like to do is to make my @Service return "detached" entities to the frontend, so it can freely and securely manipulate these objects.
That seems to be the default behavior "out of the box" (?) but that changes when I happen to use Spring transactions.
Here's a simplified test case :
Basically, the test succeeds... except when I try to use it in a @Transactional setup.Code:@Entity public class Record implements Serializable { @Id @GeneratedValue(generator = "uuid") private String id; public String getId() { return id; } public void setId(String id) { this.id = id; } private String title; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } private boolean published = false; public boolean isPublished() { return published; } public void setPublished(boolean published) { this.published = published; } } public interface RecordRepository extends JpaRepository<RecordRepository, String> { } @Service public class RecordService { @Resource private RecordRepository recordRepository; @Transactional public Record createRecord(Record recordRemote) { Record recordLocal = new Record(); recordLocal.setTitle(recordRemote.getTitle()); recordLocal = recordRepository.save(recordLocal); return recordLocal; } @Transactional public Record updateRecord(Record recordRemote) { Record recordLocal = recordRepository.findOne(recordRemote.getId()); recordLocal.setTitle(recordRemote.getTitle()); recordLocal = recordRepository.save(recordLocal); return recordLocal; } } @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "/beans.xml") @TestExecutionListeners(TransactionalTestExecutionListener.class) public class AppTest extends AbstractJUnit4SpringContextTests { @Resource private RecordService recordService; @Test @Transactional public void test1() { String TITLE = "my title"; Record record = new Record(); record.setTitle(TITLE); record = recordService.createRecord(record); assertEquals(TITLE, record.getTitle()); TITLE = "another title"; record.setTitle(TITLE); record.setPublished(true); // that shouldn't have any impact on the JPA entity (cache) record = recordService.updateRecord(record); assertEquals(TITLE, record.getTitle()); assertFalse(record.isPublished()); // fails when using @Transactional } }
So what's going on here ? Why does Spring TX have such an impact ?
And, back to my initial goal, how can I easily returned detached entities out of my @Service methods?
I suppose I could clone all my objects but I'd prefer to take advantage of JPA capabilities if possible...
Environnement : Spring 3.0.7, Spring Data JPA 1.0.2, EclipseLink 2.2.1 with PostgreSQL.
Thanks a lot!


Reply With Quote
