DATAJPA-622 - AbstractPersistable.isNew() is now annotated with @Transient.

We now mark AbstractPersistable.isNew() property as @Transient for JPA in order to make sure that no JPA provider complains about a missing setter in case a user derives a domain entity from AbstractPersistable. Without this it isn't possible to bootstrap a PersistenceContext.

Original pull request: #115.
This commit is contained in:
Thomas Darimont
2014-11-12 18:27:49 +01:00
committed by Oliver Gierke
parent e10b031207
commit 55382f58a2
6 changed files with 194 additions and 8 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2008-2011 the original author or authors.
* Copyright 2008-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,9 +18,9 @@ package org.springframework.data.jpa.domain;
import java.io.Serializable;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import org.springframework.data.domain.Persistable;
@@ -29,6 +29,7 @@ import org.springframework.data.domain.Persistable;
* {@link #equals(Object)} and {@link #hashCode()} based on that id.
*
* @author Oliver Gierke
* @author Thomas Darimont
* @param <PK> the the of the entity
*/
@MappedSuperclass
@@ -36,9 +37,7 @@ public abstract class AbstractPersistable<PK extends Serializable> implements Pe
private static final long serialVersionUID = -5554308939380869754L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private PK id;
@Id @GeneratedValue private PK id;
/*
* (non-Javadoc)
@@ -60,11 +59,13 @@ public abstract class AbstractPersistable<PK extends Serializable> implements Pe
this.id = id;
}
/*
* (non-Javadoc)
/**
* Must be {@link Transient} in order to ensure that no JPA provider complains because of a missing setter.
*
* @see DATAJPA-622
* @see org.springframework.data.domain.Persistable#isNew()
*/
@Transient
public boolean isNew() {
return null == getId();
@@ -120,4 +121,4 @@ public abstract class AbstractPersistable<PK extends Serializable> implements Pe
return hashCode;
}
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.jpa.domain.sample;
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.data.jpa.domain.AbstractPersistable;
/**
* @author Thomas Darimont
*/
@Entity
@Table(name = "customAbstractPersistable")
public class CustomAbstractPersistable extends AbstractPersistable<UUID> {
private static final long serialVersionUID = 1L;
@Id
@Override
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(name = "task_id", columnDefinition = "BINARY(16)")
public UUID getId() {
return super.getId();
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.jpa.repository;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.sample.CustomAbstractPersistable;
import org.springframework.data.jpa.repository.sample.CustomAbstractPersistableRepository;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
/**
* @author Thomas Darimont
*/
@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:config/namespace-autoconfig-context.xml" })
public class CustomAbstractPersistableIntegrationTests {
@Autowired CustomAbstractPersistableRepository repository;
/**
* @see DATAJPA-622
*/
@Test
public void shouldBeAbleToSaveAndLoadCustomPersistableWithUuidId() {
CustomAbstractPersistable entity = new CustomAbstractPersistable();
CustomAbstractPersistable saved = repository.save(entity);
CustomAbstractPersistable found = repository.findOne(saved.getId());
assertThat(found, is(saved));
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.jpa.repository;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.sample.CustomAbstractPersistable;
import org.springframework.data.jpa.repository.sample.CustomAbstractPersistableRepository;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
/**
* @author Thomas Darimont
*/
@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:config/namespace-autoconfig-context.xml" })
public class CustomAbstractPersistableIntegrationTests {
@Autowired CustomAbstractPersistableRepository repository;
/**
* @see DATAJPA-622
*/
@Test
public void shouldBeAbleToSaveAndLoadCustomPersistableWithUuidId() {
CustomAbstractPersistable entity = new CustomAbstractPersistable();
CustomAbstractPersistable saved = repository.save(entity);
CustomAbstractPersistable found = repository.findOne(saved.getId());
assertThat(found, is(saved));
}
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.jpa.repository.sample;
import java.util.UUID;
import org.springframework.data.jpa.domain.sample.CustomAbstractPersistable;
import org.springframework.data.repository.CrudRepository;
/**
* @author Thomas Darimont
*/
public interface CustomAbstractPersistableRepository extends CrudRepository<CustomAbstractPersistable, UUID> {}

View File

@@ -35,6 +35,7 @@
<class>org.springframework.data.jpa.domain.sample.SpecialUser</class>
<class>org.springframework.data.jpa.domain.sample.User</class>
<class>org.springframework.data.jpa.domain.sample.VersionedUser</class>
<class>org.springframework.data.jpa.domain.sample.CustomAbstractPersistable</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
<persistence-unit name="querydsl">
@@ -42,6 +43,7 @@
<class>org.springframework.data.jpa.domain.sample.MailSender</class>
<class>org.springframework.data.jpa.domain.sample.MailUser</class>
<class>org.springframework.data.jpa.domain.sample.User</class>
<class>org.springframework.data.jpa.domain.sample.CustomAbstractPersistable</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
<persistence-unit name="cdi">
@@ -83,6 +85,7 @@
<class>org.springframework.data.jpa.domain.sample.MailSender</class>
<class>org.springframework.data.jpa.domain.sample.MailUser</class>
<class>org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformationIntegrationTests$Sample</class>
<class>org.springframework.data.jpa.domain.sample.CustomAbstractPersistable</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
@@ -95,6 +98,7 @@
<class>org.springframework.data.jpa.domain.sample.MailSender</class>
<class>org.springframework.data.jpa.domain.sample.MailUser</class>
<class>org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformationIntegrationTests$Sample</class>
<class>org.springframework.data.jpa.domain.sample.CustomAbstractPersistable</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
<persistence-unit name="metadata_oj">
@@ -104,6 +108,7 @@
<class>org.springframework.data.jpa.domain.sample.MailSender</class>
<class>org.springframework.data.jpa.domain.sample.MailUser</class>
<class>org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformationIntegrationTests$Sample</class>
<class>org.springframework.data.jpa.domain.sample.CustomAbstractPersistable</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="openjpa.jdbc.DBDictionary" value="hsql" />