【问题标题】:Why is the id null in the entity after saveandflush but not null in the database?为什么saveandflush后实体中的id为空,而数据库中的id不为空?
【发布时间】:2017-04-02 23:40:57
【问题描述】:

我使用最新的 Spring BootSpring Data JPAHibernate。使用的数据库是 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);
}

我怀疑会话存在问题,数据尚未提交。我对吗?如何解决?谢谢!

【问题讨论】:

    标签: java oracle hibernate spring-data-jpa id-generation


    【解决方案1】:

    问题解决了!

    地址实体中getter getId之前有一个@Id注解。

    刚刚去掉注释

    之前:

    @Id
    public long getId() {
        return id;
    }
    

    之后:

    public long getId() {
        return id;
    }
    

    【讨论】:

    • 为什么这能解决问题?
    • Hibernate 可能检测到该注释并赋予其优先于另一个注释。这导致休眠只考虑 getter 和 setter 上的注释。因此,指定使用序列的注释将被忽略。
    【解决方案2】:

    我遇到了类似的问题。我能够将实体保存到数据库中,并且 id 值在数据库中。但是当我通过 REST 接口检索实体时,id 属性为空。在我的情况下,问题是由于 spring-data-rest 中 HATEOS 支持的副作用,其中 id 没有作为属性返回,而是作为 HATEOS 自链接 url 返回。为了解决这个问题,我的项目中必须有以下类:

    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));
        }    
    }
    

    【讨论】:

      猜你喜欢
      • 2020-08-29
      • 2020-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-31
      • 2015-02-20
      相关资源
      最近更新 更多