在jpa中检索自动生成的id,给出null值

时间:2017-11-02 06:52:09

标签: java postgresql jpa

我有一个Patient实体类,它自动生成一个id:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "personId", nullable = false, unique = true)
private Long personId;

public void copy (Patients patient) {

    if (patient.getNationality() != null)
        this.setNationality(patient.getNationality());
    if (patient.getGivenName() != null)
        this.setGivenName(patient.getGivenName());
    if (patient.getMiddleName() != null)
        this.setMiddleName(patient.getMiddleName());
    if (patient.getPrefix() != null)
        this.setPrefix(patient.getPrefix());

}

 /**
 * @return PERSONID
 */
public int getPersonId() {
    return personId;
}

我在PersonDaoImpl中的addPerson:

public Patients addPerson(Patients person) {

    Patients p = new Patients(person);
    try {
        em = factory.createEntityManager();
        em.getTransaction().begin();
        SimpleDateFormat sdfr = new SimpleDateFormat("yyyy-MM-
        dd'T'HH:mm:ss.SSS+05:30");
        Date date = new Date();
        String dateCreated = sdfr.format(date);
        p.setDateCreated(dateCreated);

        em.persist(p);
        em.getTransaction().commit();
    } catch (Exception e) {
        em.getTransaction().rollback();
        log.error("Exception caught :: " + e);
        p = null;
    }

    em.close();
    return p;
}

我的更新api in person服务类:

@PUT
@Path("/person-manager-resource/updatePersonById")
@Produces("application/json")
@Consumes("application/json")
public Response update(Patients person) {
    log.info("Inside UpdatePerson");
    log.info(person.getPersonId());
    dao = new PersonDaoImpl();
    ObjectMapper mapper = new ObjectMapper();

    person1 = dao.updatePerson(person);
    String result = "";
    try {
        result = mapper.writeValueAsString(person1);
        log.info("Person updated :: " + result);
    } catch (JsonProcessingException e) {
        log.info("Exception Caught :: " + e);
    }
    if (person1 != null) {
        return Response.
                status(Response.Status.OK.getStatusCode()).
                entity(result).
                build();
    } else {
        return Response.
                status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).
                entity(result).
                build();
    }
}

的updatePerson:

public Patients updatePerson(Patients updatedPatient) {

    Patients dbPatient = new Patients();
    TypedQuery<Patients> query = null;
    ObjectMapper mapper = new ObjectMapper();
    try {
        em = factory.createEntityManager();
        String identifier = updatedPatient.getPersonIdentifiers().getIdentifier();
        String queryStr = "SELECT c FROM Patients c where c.personIdentifiers.identifier = '" + identifier + "'";
        query = em.createQuery(queryStr, Patients.class);           
        dbPatient = query.getSingleResult();
        dbPatient.copy(updatedPatient);
        em.getTransaction().begin();            
        em.merge(dbPatient);
        em.getTransaction().commit();
    } catch (Exception e) {
        log.error("Exception caught :: " + e);
        em.getTransaction().rollback();
        dbPatient = null;
    }
    em.close();
    return dbPatient;
}

我通过我的REST api传递一个json对象来创建一个患者条目:

{
"personId": 5,
"prefix": null,
"givenName": "Pooja roy",
"middleName": null
}

现在情况正常。我在一个应该更新对象的api中获取相同的对象,该对象现在包含自动生成的personId。我传递了Patients实体对象中的json。当我打印整个对象时,personId为空。

由于它是null和主键,我无法进行合并。我必须手动更新数据库对象,这是一个非常漫长的过程。

任何想法为什么它会变为空以及如何检索它?

我正在使用postgres。

2 个答案:

答案 0 :(得分:1)

我认为整个问题是由updatePerson方法的实现引起的。您应该按如下方式实现该方法,它应该按预期工作,假设updatedPatient实例是一个持久实体(意味着它设置了一个ID字段):

public Patients updatePerson(Patients updatedPatient) {
    Patients mergedPatient = new Patients();

    try {
        em = factory.createEntityManager();
        em.getTransaction().begin();            

        mergedPatient = em.merge(updatedPatient); 

        em.getTransaction().commit();
    } catch (Exception e) {
        log.error("Exception caught :: " + e);
        em.getTransaction().rollback();
    }
    em.close();
    return mergedPatient;
}

现在mergedPatient应该包含同步状态。

<强>更新

替代解决方案

无论出于何种原因,您都无法在ID字段中使用setter。然后以下可能会解决您的问题:

public Patients updatePerson(Patients updatedPatient) {

Patients dbPatient = new Patients();

    try {
        em = factory.createEntityManager();
        String identifier = updatedPatient.getPersonIdentifiers().getIdentifier();

        em.getTransaction().begin();
        dbPatient = em.find(Patients.class, Long.parseLong(identifier));
        dbPatient.copy(updatedPatient);
        em.getTransaction().commit();
    } catch (Exception e) {
        // ..:
        dbPatient = null;
    }
    em.close();
    return dbPatient;
}

由于em.find()方法在事务内部执行,因此返回的对象被管理,这意味着在事务提交时,对返回的实例的任何更改都将与数据库同步。

答案 1 :(得分:0)

PersonId是自动生成的ID。所以,jpa不允许我为personId设置一个setter。我们在实体类中只有getPersonId()方法。

因此,在updatePerson(患者人员)中,当我传递person对象时,会调用每个setter并因此创建对象。由于personId没有setter方法,因此在该对象中返回null。