为什么saveandflush后实体中id为null,而数据库中不为null?
Why is the id null in the entity after saveandflush but not null in the database?
我使用最新的 Spring Boot 和 Spring Data JPA 和 Hibernate 。使用的数据库是Oracle 11G。几天来我一直在寻找解决方案,但没有任何效果。
我努力 检索数据库中新插入(成功)的实体的 ID。我使用序列和触发器。例如
实体:
@Entity
public class Address implements Serializable {
@Id
@Column(name = "ID", nullable = false, precision = 0)
@SequenceGenerator(name = "SEQ_ID_GEN", sequenceName = "GI2S1.SEQ_ID", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ID_GEN")
private long id;
private String addressLine;
private String addressLine2;
private String city;
private String postalCode;
@Id
public long getId() {
return id;
}
Getters & setters omitted...
触发器:
CREATE OR REPLACE TRIGGER SEQ_ADDRESS_TRIG
BEFORE INSERT ON ADDRESS
FOR EACH ROW
BEGIN
SELECT SEQ_ID.nextval
INTO :new.id
FROM dual;
END;
/
顺序:
CREATE SEQUENCE SEQ_ID START WITH 1 INCREMENT BY 1 MINVALUE 1;
查询在控制器中执行。例如
@Controller
@RequestMapping("/address")
public class AddressController {
@Autowired
private AddressRepository addressRepository;
@Transactional
public Address saveAddress(Address address) {
try {
return addressRepository.saveAndFlush(address);
} catch (Exception ex) {
System.out.println(ex);
}
return null;
}
@PostMapping("/create")
public String create(@ModelAttribute Address address) {
Address saved = saveAddress(address);
long id = saved.getId();
System.out.println(saved);
return (id > 0) ?
"redirect:/address/find?id=" + id
:
"redirect:/address/list";
}
findAll 后的结果
{"id":81,"addressLine":"aa","addressLine2":"a","city":"a","postalCode" :"a"}
但这里是 System.out.println(saved);
之后的对象
Address{id=0, addressLine='aa', addressLine2='a', city='a',
postalCode='a'}
存储库:
@Transactional
public interface AddressRepository extends JpaRepository<Address, Long> {
List<Address> findByCity(String city);
}
我怀疑会话有问题,数据尚未提交。我对吗?如何解决?谢谢!
问题已解决!
地址实体中gettergetId前有@Id注解
刚刚删除注释
之前:
@Id
public long getId() {
return id;
}
之后:
public long getId() {
return id;
}
我遇到了类似的问题。我能够很好地将实体持久保存到数据库中,并且 id 值在数据库中。但是当我通过 REST 接口检索实体时,id 属性为空。我的问题是由于 spring-data-rest 中 HATEOS 支持的副作用,其中 id 不作为属性返回,而是作为 HATEOS 自身返回 link url .要解决此问题,我必须在我的项目中包含以下 class:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter;
import javax.persistence.EntityManager;
import javax.persistence.metamodel.Type;
@Configuration
public class RepositoryConfig extends RepositoryRestConfigurerAdapter {
@Autowired
private EntityManager entityManager;
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.exposeIdsFor(
entityManager.getMetamodel().getEntities().stream()
.map(Type::getJavaType)
.toArray(Class[]::new));
}
}
我使用最新的 Spring Boot 和 Spring Data JPA 和 Hibernate 。使用的数据库是Oracle 11G。几天来我一直在寻找解决方案,但没有任何效果。 我努力 检索数据库中新插入(成功)的实体的 ID。我使用序列和触发器。例如
实体:
@Entity
public class Address implements Serializable {
@Id
@Column(name = "ID", nullable = false, precision = 0)
@SequenceGenerator(name = "SEQ_ID_GEN", sequenceName = "GI2S1.SEQ_ID", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ID_GEN")
private long id;
private String addressLine;
private String addressLine2;
private String city;
private String postalCode;
@Id
public long getId() {
return id;
}
Getters & setters omitted...
触发器:
CREATE OR REPLACE TRIGGER SEQ_ADDRESS_TRIG
BEFORE INSERT ON ADDRESS
FOR EACH ROW
BEGIN
SELECT SEQ_ID.nextval
INTO :new.id
FROM dual;
END;
/
顺序:
CREATE SEQUENCE SEQ_ID START WITH 1 INCREMENT BY 1 MINVALUE 1;
查询在控制器中执行。例如
@Controller
@RequestMapping("/address")
public class AddressController {
@Autowired
private AddressRepository addressRepository;
@Transactional
public Address saveAddress(Address address) {
try {
return addressRepository.saveAndFlush(address);
} catch (Exception ex) {
System.out.println(ex);
}
return null;
}
@PostMapping("/create")
public String create(@ModelAttribute Address address) {
Address saved = saveAddress(address);
long id = saved.getId();
System.out.println(saved);
return (id > 0) ?
"redirect:/address/find?id=" + id
:
"redirect:/address/list";
}
findAll 后的结果 {"id":81,"addressLine":"aa","addressLine2":"a","city":"a","postalCode" :"a"}
但这里是 System.out.println(saved);
之后的对象Address{id=0, addressLine='aa', addressLine2='a', city='a',
postalCode='a'}
存储库:
@Transactional
public interface AddressRepository extends JpaRepository<Address, Long> {
List<Address> findByCity(String city);
}
我怀疑会话有问题,数据尚未提交。我对吗?如何解决?谢谢!
问题已解决!
地址实体中gettergetId前有@Id注解
刚刚删除注释
之前:
@Id
public long getId() {
return id;
}
之后:
public long getId() {
return id;
}
我遇到了类似的问题。我能够很好地将实体持久保存到数据库中,并且 id 值在数据库中。但是当我通过 REST 接口检索实体时,id 属性为空。我的问题是由于 spring-data-rest 中 HATEOS 支持的副作用,其中 id 不作为属性返回,而是作为 HATEOS 自身返回 link url .要解决此问题,我必须在我的项目中包含以下 class:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter;
import javax.persistence.EntityManager;
import javax.persistence.metamodel.Type;
@Configuration
public class RepositoryConfig extends RepositoryRestConfigurerAdapter {
@Autowired
private EntityManager entityManager;
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.exposeIdsFor(
entityManager.getMetamodel().getEntities().stream()
.map(Type::getJavaType)
.toArray(Class[]::new));
}
}