I have a Patients entity class which auto generates an 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;
}
My addPerson in PersonDaoImpl :
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;
}
My update api in person service class:
#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;
}
I pass a json object through my REST api to create a patient entry:
{
"personId": 5,
"prefix": null,
"givenName": "Pooja roy",
"middleName": null
}
Now this is going fine. I take the same object, which now contains the auto-generated personId, in an api which is supposed to update the object. I pass the json in the Patients entity object. When I print this whole object, the personId is null.
Since it is null and primary key, I can't do a merge. I have to manually update the database object, which is a very lengthy process.
Any ideas why it is coming as null and how I can retrieve it?
I am using postgres.
I think the whole problem is caused by the implementation of the updatePerson method. You should implement the method as follows and it should work as expected, assuming the updatedPatient instance is a persistent entity (meaning it has an ID field set):
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;
}
Now mergedPatient should contain the synchronized state.
Update:
alternative solution
For whatever reason you cannot use a setter for the ID field. Then the following might solve your problem:
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;
}
As the em.find() method is executed inside of a transaction, the object returned is managed, which means any changes to that returned instance will be synchronized with the database when the transaction commits.
PersonId is an auto generated id. So, jpa doesn't allow for me to set a setter for personId. We only have getPersonId() method in the entity class.
So, in updatePerson(Patients person), when I am passing the person object, every setter is called and the object is thus created. Since, personId doesn't have a setter method, it is returned as null in that object.
Related
I have an old java code and I'm quite new to java spring, I need to read json files and merge data from entity to Oracle database.
I test my code without the entityManager.merge() and it works well.
But now, I tried with merge and got an EJBException
javax.ejb.EJBException: EJB Exception: : javax.persistence.TransactionRequiredException: The method public abstract java.lang.Object javax.persistence.EntityManager.merge(java.lang.Object) must be called in the context of a transaction.
at weblogic.persistence.BasePersistenceContextProxyImpl.validateInvocation(BasePersistenceContextProxyImpl.java:148)
at weblogic.persistence.BasePersistenceContextProxyImpl.invoke(BasePersistenceContextProxyImpl.java:103)
at weblogic.persistence.TransactionalEntityManagerProxyImpl.invoke(TransactionalEntityManagerProxyImpl.java:138)
at weblogic.persistence.BasePersistenceContextProxyImpl.invoke(BasePersistenceContextProxyImpl.java:91)
at com.sun.proxy.$Proxy592.merge(Unknown Source)
at be.smals.ideploy.manager.ReleaseManager.updateReleases(ReleaseManager.java:69)
at be.smals.ideploy.manager.ReleaseManager.getActiveReleaseList(ReleaseManager.java:144)
This is my code :
#Stateless
#Local
#TransactionAttribute(TransactionAttributeType.SUPPORTS)
public class ReleaseManager {
private static final Logger LOGGER = LoggerFactory.getLogger(ReleaseManager.class);
private static final String STATUS_CLOSED = "inactive";
private static final String STATUS_OPEN = "active";
private Integer cpt_active = 0;
private Integer cpt_inactive = 0;
#PersistenceContext(unitName = "deployment")
private EntityManager em;
public void updateReleases() {
try {
for (GetReleaseList releaseList : getRelease(STATUS_OPEN)) {
Service service_active = new Service();
Release release_active = new Release();
List<ResponseJson> response = getResponse(STATUS_OPEN);
service_active.setId(response.get(cpt_active).getResult().getService_id());
release_active.setService(service_active);
String releaseId = releaseList.getNumber();
String releaseId_format = releaseId.replace("CHG","");
release_active.setId(releaseId_format);
release_active.setName(releaseList.getShortDescription());
release_active.setActive(Boolean.TRUE);
LOGGER.info("RELEASE NUMBER FORMATED : " + releaseId_format);
em.merge(release_active);
cpt_active += 1;
}
for (GetReleaseList releaseList : getRelease(STATUS_CLOSED)) {
Service service_inactive = new Service();
Release release_inactive = new Release();
List<ResponseJson> response = getResponse(STATUS_CLOSED);
service_inactive.setId(response.get(cpt_inactive).getResult().getService_id());
release_inactive.setService(service_inactive);
String releaseId = releaseList.getNumber();
String releaseId_format = releaseId.replace("CHG","");
release_inactive.setId(releaseId_format);
release_inactive.setName(releaseList.getShortDescription());
release_inactive.setActive(Boolean.FALSE);
LOGGER.info("RELEASE NUMBER FORMATED : " + releaseId_format);
em.merge(release_inactive);
cpt_inactive += 1;
}
}catch (TransactionException ex) {
throw new TechnicalException(ex);
}
Query q = em.createQuery("update Deployment d set d.release = null where d.status.id = :status and d.release.id in ( select r.id from Release r where r.active = :active) ");
LOGGER.info("Create Query : " + q);
q.setParameter("status", State.CREATING);
q.setParameter("active", Boolean.FALSE);
int updated = q.executeUpdate();
LOGGER.info("Updated release.id of " + updated + " deployments");
}
// getRelease element for Release entity except service ID
private List<GetReleaseList> getRelease(String STATUS) {
Gson gson = new Gson();
BufferedReader buffer_reader = null;
LOGGER.info(STATUS);
try {
buffer_reader = new BufferedReader(new FileReader("/tmp/snow/Release_manager_"+STATUS+".json"));
File File_snow = new File("/tmp/snow/Release_manager_"+STATUS+".json");
boolean exists = File_snow.exists();
LOGGER.info(String.valueOf(exists));
}catch (FileNotFoundException ex){
ex.printStackTrace();
}
RESTResponseJson response = gson.fromJson(buffer_reader, RESTResponseJson.class);
return response.getResult();
}
// getServiceID element for Release entity attribute Long service_id
private static List<ResponseJson> getResponse(String STATUS){
Gson gson_service = new Gson();
BufferedReader buffer_reader_service = null;
try {
buffer_reader_service = new BufferedReader(new FileReader("/tmp/snow/Service_id_"+STATUS+".json"));
}catch (FileNotFoundException ex){
ex.printStackTrace();
}
Response response_service = gson_service.fromJson(buffer_reader_service, Response.class);
return response_service.getResponse();
}
public List<Service> getServiceList(){
TypedQuery<Service> q = em.createQuery("SELECT s from Service", Service.class);
List<Service> services = q.getResultList();
return services;
}
public List<ReleaseTO> getInActiveReleaseList() {
TypedQuery<ReleaseTO> query = em.createQuery("select new be.smals.ideploy.to.ReleaseTO(r.id, r.name) from Release r where r.active=:active ORDER BY UPPER(r.name)", ReleaseTO.class);
query.setParameter("active", Boolean.FALSE);
List<ReleaseTO> result = query.getResultList();
return result;
}
public List<ReleaseTO> getActiveReleaseList() {
updateReleases();
TypedQuery<ReleaseTO> query = em.createQuery("select new be.smals.ideploy.to.ReleaseTO(r.id, r.name) from Release r where r.active=:active ORDER BY UPPER(r.name)", ReleaseTO.class);
query.setParameter("active", Boolean.TRUE);
List<ReleaseTO> result = query.getResultList();
return result;
}
public List<ReleaseTO> getReleaseList() {
TypedQuery<ReleaseTO> query = em.createQuery("select new be.smals.ideploy.to.ReleaseTO(r.id, r.name) from Release r ORDER BY UPPER(r.name)", ReleaseTO.class);
List<ReleaseTO> result = query.getResultList();
return result;
}
}
As suggest the error, is the #TransactionAttribute that don't correspond to my context, if somebody can explain the differencies for TransactionAttributeType.
I also read that it could come from #Stateless statement.
From https://docs.oracle.com/javaee/6/api/javax/ejb/TransactionAttributeType.html
SUPPORTS: If the client calls with a transaction context, the container performs the same steps as described in the REQUIRED case.
REQUIRED: If a client invokes the enterprise bean's method while the client is associated with a transaction context, the container invokes the enterprise bean's method in the client's transaction context.
I think you want "REQUIRED"
When I am trying to save a new object using create case method..error is coming at session .saveORUpdate(createcasevalueentity)... I.E. illegal attempt to associate a collection with two open session
#Override
public Map createCase(Patientcase createCase, Integer patientID, String userName
// changes by sahil.sharma08 start here
/* ,List surgeonsID,
List anesthesiologistID, Integer specialityID, Integer operationTheaterNoID
// changes by sahil.sharma08 start here
*/) throws Exception
{
LOGGER.info("Logger Name: " + LOGGER.getName());
Session session = null;
Map<String, String> result = new HashMap<String, String>();
Patient createPatientEntity;
try
{
// opens a new session from the session factory
SessionFactory sessionFactory = HibernateUtilities.createSessionFactory();
// For logging audit record
AuditLogInterceptor interceptor = new AuditLogInterceptor();
session = sessionFactory.withOptions().interceptor(interceptor).openSession();
interceptor.setSession(session);
interceptor.setUserName(userName);
session.getTransaction().begin();
createPatientEntity = (Patient) session.get(Patient.class, patientID);
createCase.setPatient(createPatientEntity);
if (createPatientEntity == null)
{
result.put("Error", "Patient ID does not Exist");
return result;
}
// changes by sahil.sharma08 start here
//Long caseID = createCase.getCaseId();
// changes by sahil.sharma08 end here
Query query = session.createQuery("delete FROM Casevalues cve WHERE cve.patientcase.caseId = ?");
// changes by sahil.sharma08 start here
//query.setParameter(0, caseID);
query.setParameter(0, createCase.getCaseId());
// changes by sahil.sharma08 end here
query.executeUpdate();
if(createCase.getSpeciality()!=null && !createCase.getSpeciality().equals(""))
{
Casevalues createCaseValuesEntity = new Casevalues();
createCaseValuesEntity.setPatientcase(createCase);
Entityvalues valuesEntity =(Entityvalues) session.get(Entityvalues.class, new Integer(createCase.getSpeciality()));
createCaseValuesEntity.setEntityvalues(valuesEntity);
session.saveOrUpdate(createCaseValuesEntity);
createCase.setSpeciality(valuesEntity.getEntityValue());
}
// changes by sahil.sharma08 end here
session.saveOrUpdate(createCase); // Persisting createCase Entity in database
// changes by sahil.sharma08 end here
result.put("patientId", createCase.getPatient().getPatientId().toString());
result.put("caseId", createCase.getCaseId().toString());
session.getTransaction().commit(); // Session commit
}
catch (Exception e)
{
if (session != null && session.getTransaction() != null)
{
// If transaction is open,rollback
session.getTransaction().rollback();
}
LOGGER.log(Level.INFO, "Exception occur", e);
throw e;
}
finally
{
if (session != null)
{
session.close(); // Session close
}
}
return result;
}
I am working under a project that is update the data's in MySQL table using Hibernate. Whenever I run the project, the exception is shown as below.
[Batch update returned unexpected row count from update [0]; actual
row count: 0; expected: 1]
Controller
#RequestMapping(value = "/disableEmployeeMaster", method = RequestMethod.POST)
public #ResponseBody void disableEmployee(HttpServletRequest request)
{
EmployeeMaster employeeMaster = new EmployeeMaster();
try
{
String employeeId = request.getParameter("employeeId");
employeeMaster.setIsDel("Y");
mainService.disableEmployee(employeeId , employeeMaster);
}
catch(Exception e)
{
logger.error(e.getMessage());
}
}
Service Implementation
#Override
public void disableEmployee(String Id, EmployeeMaster employeeMaster) {
Session session = null;
Transaction transaction = null;
try
{
session = sessionFactory.openSession();
transaction = session.beginTransaction();
session.update(Id, employeeMaster);
transaction.commit();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
finally
{
session.close();
}
}
You have't set employeeId to EmployeeMaster class object.
to update any entity needs it's primary key.
You can refer following code :
employeeMaster.setEmployeeId(employeeId);
Controller
#RequestMapping(value = "/disableEmployeeMaster", method = RequestMethod.POST)
public #ResponseBody void disableEmployee(HttpServletRequest request)
{
EmployeeMaster employeeMaster = new EmployeeMaster();
try
{
String employeeId = request.getParameter("employeeId");
employeeMaster.setEmployeeId(employeeId);
employeeMaster.setIsDel("Y");
mainService.disableEmployee(employeeId , employeeMaster);
}
catch(Exception e)
{
logger.error(e.getMessage());
}
}
ninja is an awesome framework but coming from a spring background, I need to use spring data jpa with ninja.
I want to Autowire a JpaRepository and use it in ninja. Although ninja uses Guice Inject. I keep getting a No implementations found for my class.
the repository:
public interface PortalUserRepository extends JpaRepository<PortalUser, Long> {
PortalUser getPortalUserByUsername(String username);
PortalUser getPortalUserByEmail(String email);
}
the injection
public class SetupDaoV2 {
#Inject
PortalUserRepository portalUserRepository;
public void setup() {
try {
List<PortalUser> portalUsers = portalUserRepository.findAll();
if (portalUsers.size() == 0) {
// Create a new user and save it
PortalUser portalUser = new PortalUser("lsadjfl", "lsdlfs", "kkk lll",
"llskfls#gmail.com", "lsdlfss#",
"lsdfls#gmail.com",
new Timestamp(System.currentTimeMillis()), Boolean.TRUE,
Boolean.TRUE, GenericStatusConstant.ACTIVE, Boolean.TRUE
);
portalUserRepository.save(portalUser);
}
}catch (Exception ex){
ex.printStackTrace();
}
}
}
the error
com.google.inject.CreationException: Unable to create injector, see
the following errors:
1) No implementation for com.bw.dd.dsl.repository.PortalUserRepository was bound.
Well, I finally had to implement the whole thing. A shame I couldn't port the wonderful features from spring data jpa into ninja. I coulda used spring, but for office policy on the project.
If someone finds a way, pls holla.
public abstract class JpaRepository<E, K> {
public abstract void create(E entity);
public abstract void edit(E entity) throws Exception;
public abstract void remove(K key) throws IllegalOrphanException, NonexistentEntityException;
public abstract List<E> findAll();
public abstract E findOne(K key);
public abstract int count();
}
public class PortalUserRepository extends JpaRepository<PortalUser, Long> {
private EntityManagerFactory emf = null;
public PortalUserRepository() {
}
public PortalUserRepository(EntityManagerFactory emf) {
this.emf = emf;
}
public EntityManager getEntityManager() {
return emf.createEntityManager();
}
public void create(PortalUser entity) {
if (entity.getUserTokens() == null) {
entity.setUserTokens(new ArrayList<UserToken>());
}
EntityManager em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
Collection<UserToken> attachedUserTokens = new ArrayList<UserToken>();
for (UserToken userTokensUserTokenToAttach : entity.getUserTokens()) {
userTokensUserTokenToAttach = em.getReference(userTokensUserTokenToAttach.getClass(), userTokensUserTokenToAttach.getId());
attachedUserTokens.add(userTokensUserTokenToAttach);
}
entity.setUserTokens(attachedUserTokens);
em.persist(entity);
for (UserToken userTokensUserToken : entity.getUserTokens()) {
PortalUser oldPortalUserOfUserTokensUserToken = userTokensUserToken.getPortalUser();
userTokensUserToken.setPortalUser(entity);
userTokensUserToken = em.merge(userTokensUserToken);
if (oldPortalUserOfUserTokensUserToken != null) {
oldPortalUserOfUserTokensUserToken.getUserTokens().remove(userTokensUserToken);
oldPortalUserOfUserTokensUserToken = em.merge(oldPortalUserOfUserTokensUserToken);
}
}
em.getTransaction().commit();
} finally {
if (em != null) {
em.close();
}
}
}
public void edit(PortalUser entity) throws Exception {
EntityManager em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
PortalUser persistentPortalUser = em.find(PortalUser.class, entity.getId());
Collection<UserToken> userTokensOld = persistentPortalUser.getUserTokens();
Collection<UserToken> userTokensNew = entity.getUserTokens();
List<String> illegalOrphanMessages = null;
for (UserToken userTokensOldUserToken : userTokensOld) {
if (!userTokensNew.contains(userTokensOldUserToken)) {
if (illegalOrphanMessages == null) {
illegalOrphanMessages = new ArrayList<String>();
}
illegalOrphanMessages.add("You must retain UserToken " + userTokensOldUserToken + " since its entity field is not nullable.");
}
}
if (illegalOrphanMessages != null) {
throw new IllegalOrphanException(illegalOrphanMessages);
}
Collection<UserToken> attachedUserTokensNew = new ArrayList<UserToken>();
for (UserToken userTokensNewUserTokenToAttach : userTokensNew) {
userTokensNewUserTokenToAttach = em.getReference(userTokensNewUserTokenToAttach.getClass(), userTokensNewUserTokenToAttach.getId());
attachedUserTokensNew.add(userTokensNewUserTokenToAttach);
}
userTokensNew = attachedUserTokensNew;
entity.setUserTokens(userTokensNew);
entity = em.merge(entity);
for (UserToken userTokensNewUserToken : userTokensNew) {
if (!userTokensOld.contains(userTokensNewUserToken)) {
PortalUser oldPortalUserOfUserTokensNewUserToken = userTokensNewUserToken.getPortalUser();
userTokensNewUserToken.setPortalUser(entity);
userTokensNewUserToken = em.merge(userTokensNewUserToken);
if (oldPortalUserOfUserTokensNewUserToken != null && !oldPortalUserOfUserTokensNewUserToken.equals(entity)) {
oldPortalUserOfUserTokensNewUserToken.getUserTokens().remove(userTokensNewUserToken);
oldPortalUserOfUserTokensNewUserToken = em.merge(oldPortalUserOfUserTokensNewUserToken);
}
}
}
em.getTransaction().commit();
} catch (Exception ex) {
String msg = ex.getLocalizedMessage();
if (msg == null || msg.length() == 0) {
Long id = entity.getId();
if (findOne(id) == null) {
throw new NonexistentEntityException("The entity with id " + id + " no longer exists.");
}
}
throw ex;
} finally {
if (em != null) {
em.close();
}
}
}
public void remove(Long key) throws IllegalOrphanException, NonexistentEntityException {
EntityManager em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
PortalUser portalUser;
try {
portalUser = em.getReference(PortalUser.class, key);
portalUser.getId();
} catch (EntityNotFoundException enfe) {
throw new NonexistentEntityException("The portalUser with id " + key + " no longer exists.", enfe);
}
List<String> illegalOrphanMessages = null;
Collection<UserToken> userTokensOrphanCheck = portalUser.getUserTokens();
for (UserToken userTokensOrphanCheckUserToken : userTokensOrphanCheck) {
if (illegalOrphanMessages == null) {
illegalOrphanMessages = new ArrayList<String>();
}
illegalOrphanMessages.add("This PortalUser (" + portalUser + ") cannot be destroyed since the UserToken " + userTokensOrphanCheckUserToken + " in its userTokens field has a non-nullable portalUser field.");
}
if (illegalOrphanMessages != null) {
throw new IllegalOrphanException(illegalOrphanMessages);
}
em.remove(portalUser);
em.getTransaction().commit();
} finally {
if (em != null) {
em.close();
}
}
}
public List<PortalUser> findAll() {
EntityManager em = getEntityManager();
try {
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
cq.select(cq.from(PortalUser.class));
Query q = em.createQuery(cq);
return q.getResultList();
} finally {
em.close();
}
}
public PortalUser findOne(Long key) {
EntityManager em = getEntityManager();
try {
return em.find(PortalUser.class, key);
} finally {
em.close();
}
}
public int count() {
EntityManager em = getEntityManager();
try {
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
Root<PortalUser> rt = cq.from(PortalUser.class);
cq.select(em.getCriteriaBuilder().count(rt));
Query q = em.createQuery(cq);
return ((Long) q.getSingleResult()).intValue();
} finally {
em.close();
}
}
public PortalUser findPortalUserByUsername(String username){
EntityManager em = getEntityManager();
try {
Query q = em.createQuery("select s from PortalUser s where s.username = '" + username + "'");
return (PortalUser)q.getSingleResult();
} finally {
em.close();
}
}
You need to mark PortalUserRepository class with #Repository as shown below:
#Repository
public interface PortalUserRepository extends JpaRepository<PortalUser, Long> {
//your methods
}
Also, ensure that you have got #EnableJPARepositories so that Spring container can scan for your repository interfaces and provide the implementations for them and then inject them into your SetupDaoV2 bean.
I have to write DAO layer for Mongo DB.
I found that this isn't so easy.
My implementation is straightforward:
delete document with the same key => and save updated it again
How possible to do it for List of elements?
For example JSON representation is next:
"airItinerary" : {
"originDestinationOptions" : {
"originDestinationOption" : [ {
"flightSegment" : [ {
"departureAirport" : {
"locationCode" : "DUB",
"codeContext" : "IATA"
},
"arrivalAirport" : {
"locationCode" : "CDG",
"codeContext" : "IATA"
},
Here is my code:
#Override
public void update(MODEL model) {
try {
Field keyField1 = getKeyField(model);
String fieldValue = getKeyFieldValue(keyField1, model);
BasicDBObject query = createQuery(keyField1.getName(), fieldValue);
DBCursor cursor = dbCollection.find(query);
if (cursor.hasNext()) {
DBObject dbObject = getDbObject(model);
dbCollection.update(query, dbObject);
} else {
throw new RuntimeException(String.format("Data status %s isn't presented at %s with value %s", keyField1.getName(), dbCollection.getFullName(), fieldValue));
}
} catch (IOException e) {
Log.getInstance().log(e.getCause());
}
}
private Field getKeyField(MODEL model) {
Field keyField = null;
for (Field field : model.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(KeyField.class)) {
keyField = field;
}
}
if (keyField == null) {
throw new RuntimeException(String.format("Couldn't find KeyField annotation at class '%s'", model.getClass().getName()));
}
return keyField;
}
private String getKeyFieldValue(Field keyField, Object model) {
String result = null;
try {
if(keyField.isAnnotationPresent(KeyField.class)) {
keyField.setAccessible(true);
result = keyField.get(model).toString();
}
if(result == null || result.equals("")) {
throw new NullPointerException();
}
} catch(NullPointerException e) {
throw new RuntimeException("KeyField property is empty");
}catch (Exception e) {
throw new RuntimeException(String.format("Couldn't find KeyField annotation at class '%s'", model.getClass().getName()));
}
return result;
}
private BasicDBObject createQuery(String key, String value) {
BasicDBObject query = new BasicDBObject();
query.put(key, value);
return query;
}
For shure should exist much better way for this result.
I can't find smt at mongo doc for achieving this result.
How to achive the same effect with Mongo tools.
It's allowed to update directly; don't need to find as the first step and this will probably cause inconsistency between update and find operation.
#Override
public void update(MODEL model) {
try {
Field keyField1 = getKeyField(model);
String fieldValue = getKeyFieldValue(keyField1, model);
BasicDBObject query = createQuery(keyField1.getName(), fieldValue);
DBObject dbObject = getDbObject(model);
dbCollection.update(query, dbObject);
/* DBCursor cursor = dbCollection.find(query);
if (cursor.hasNext()) {
DBObject dbObject = getDbObject(model);
dbCollection.update(query, dbObject);
} else {
throw new RuntimeException(String.format("Data status %s isn't presented at %s with value %s", keyField1.getName(), dbCollection.getFullName(), fieldValue));
}
*/
} catch (IOException e) {
Log.getInstance().log(e.getCause());
}
}
private Field getKeyField(MODEL model) {
Field keyField = null;
for (Field field : model.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(KeyField.class)) {
keyField = field;
break; // add a break to jump out quickly.
}
}
if (keyField == null) {
throw new RuntimeException(String.format("Couldn't find KeyField annotation at class '%s'", model.getClass().getName()));
}
return keyField;
}
Also, spring-data-mongodb is a choice to handle these kind of issues.