Ed. Although extending the base class of the repository and adding an insertion method will work, a more elegant solution seems to implement Persistable in essence. See Possible Solution 2
I am creating a service using springframework.data.jpawith Hibernate as an ORM using JpaTransactionManager.
following the bottom of the textbook.
http://www.petrikainulainen.net/spring-data-jpa-tutorial/
My object repositories are expanding org.springframework.data.repository.CrudRepository
I am working with an outdated database that uses meaningful primary keys and not automatically generated id
This situation should not occur, but I ran into it due to a test error. The order table has the significant key OrderNumber (M000001, etc.). The primary key value is generated in the code and assigned to the object before saving. The legacy database does not use automatically generated identification keys.
I have a transaction that creates a new order. Due to an error, my code generated an order number that already exists in the database (M000001)
Running the .save repository caused an update to an existing order. I want to force insert and execute a transaction due to duplicate primary key.
Insert , , . OrderLinePK, spring FindOne (ID id)
spring JPA?
jpa, spring/Hibernate . Insert Save .
, .
getSession().saveOrUpdate , , .
getSession().save , .
@Override
public Order save(Order bean) {
getSession().saveOrUpdate(bean);
return bean;
}
@Override
public Order insert(Order bean) {
getSession().save(bean);
return bean;
}
1
1.3.2 spring
http://docs.spring.io/spring-data/jpa/docs/1.4.1.RELEASE/reference/html/repositories.html
, , , , .
, . .
, . ?
. entitymanager exist ( (*) ?)
import java.io.Serializable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;
@NoRepositoryBean
public interface IBaseRepository <T, ID extends Serializable> extends JpaRepository<T, ID> {
void insert(T entity, ID id);
}
: .
. , .
import java.io.Serializable;
import javax.persistence.EntityManager;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.transaction.annotation.Transactional;
public class BaseRepositoryImpl<T, ID extends Serializable>
extends SimpleJpaRepository<T, ID> implements IBaseRepository<T, ID> {
private final EntityManager entityManager;
public BaseRepositoryImpl(Class<T> domainClass, EntityManager em) {
super(domainClass, em);
this.entityManager = em;
}
public BaseRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
super (entityInformation, entityManager);
this.entityManager = entityManager;
}
@Transactional
public void insert(T entity, ID id) {
T exists = entityManager.find(this.getDomainClass(),id);
if (exists == null) {
entityManager.persist(entity);
}
else
throw(new IllegalStateException("duplicate"));
}
}
factory bean
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import javax.persistence.EntityManager;
import java.io.Serializable;
public class BaseRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable>
extends JpaRepositoryFactoryBean<R, T, I> {
protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
return new BaseRepositoryFactory(entityManager);
}
private static class BaseRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory {
private EntityManager entityManager;
public BaseRepositoryFactory(EntityManager entityManager) {
super(entityManager);
this.entityManager = entityManager;
}
protected Object getTargetRepository(RepositoryMetadata metadata) {
return new BaseRepositoryImpl<T, I>((Class<T>) metadata.getDomainType(), entityManager);
}
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
return IBaseRepository.class;
}
}
}
,
// Define this class as a Spring configuration class
@Configuration
// Enable Spring/jpa transaction management.
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.savant.test.spring.donorservicejpa.dao.repository"},
repositoryBaseClass = com.savant.test.spring.donorservicejpa.dao.repository.BaseRepositoryImpl.class)
2
patrykos91
Persistable isNew()
import java.io.Serializable;
import javax.persistence.MappedSuperclass;
import javax.persistence.PostLoad;
import javax.persistence.PostPersist;
import javax.persistence.PostUpdate;
@MappedSuperclass
public abstract class BaseEntity implements Serializable{
protected transient boolean persisted;
@PostLoad
public void postLoad() {
this.persisted = true;
}
@PostUpdate
public void postUpdate() {
this.persisted = true;
}
@PostPersist
public void postPersist() {
this.persisted = true;
}
}
isNew() getID()
java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import org.springframework.data.domain.Persistable;
@Entity
@Table(name = "MTHSEQ")
@XmlRootElement
public class Sequence extends BaseEntity implements Serializable, Persistable<SequencePK> {
private static final long serialVersionUID = 1L;
@EmbeddedId
protected SequencePK sequencePK;
@Column(name = "NEXTSEQ")
private Integer nextseq;
public Sequence() {
}
@Override
public boolean isNew() {
return !persisted;
}
@Override
public SequencePK getId() {
return this.sequencePK;
}
public Sequence(SequencePK sequencePK) {
this.sequencePK = sequencePK;
}
public Sequence(String mthkey, Character centre) {
this.sequencePK = new SequencePK(mthkey, centre);
}
public SequencePK getSequencePK() {
return sequencePK;
}
public void setSequencePK(SequencePK sequencePK) {
this.sequencePK = sequencePK;
}
public Integer getNextseq() {
return nextseq;
}
public void setNextseq(Integer nextseq) {
this.nextseq = nextseq;
}
@Override
public int hashCode() {
int hash = 0;
hash += (sequencePK != null ? sequencePK.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
if (!(object instanceof Sequence)) {
return false;
}
Sequence other = (Sequence) object;
if ((this.sequencePK == null && other.sequencePK != null) || (this.sequencePK != null && !this.sequencePK.equals(other.sequencePK))) {
return false;
}
return true;
}
@Override
public String toString() {
return "com.savant.test.spring.donorservice.core.entity.Sequence[ sequencePK=" + sequencePK + " ]";
}
}
isNew(), , . GetId , , , PK.