I am working on a client-server project in GWT and after the user fills a form, I would like to update my database and eventually create new datas.
For that, I create a "sensor" and the system link with which it is associated. But, the "sensor" is associated with a sensor Family too and I must create the link in my table sensorFamilySensorFamilyLink but I do not managed.
Indeed, here is my code for the creation of the sensor and the link:
#Override
public void updateSensor(SystemDTO system, SensorDTO sensorDTO, String sensorFamName) {
Sensor sensor = null;
SensorFamily sensorFam = null;
if(sensorDTO.getId() <0) {
sensor = new Sensor();
sensor.fillFromDTO(sensorDTO);
sensor.create();
}
else {
sensor = Sensor.queryById(sensorDTO.getId());
sensor.fillFromDTO(sensorDTO);
sensor.update();
}
sensorFam = SensorFamily.queryByName(sensorFamName);
// Creation of the link between sensor and sensorFamily.
SensorFamilySensorLink linksensor = null;
if (!linkFam.isEmpty()) {
linksensor = linkFam.get(0); // We take the first one because there is only one.
}
if(linksensor == null) { // creation of a sensor
//List<SensorFamilySensorLink> liste = SensorFamilySensorLink.query();
linksensor = new SensorFamilySensorLink();
linksensor.setSensorId(sensor.getId());
linksensor.setSensorFamilyId(sensorFam.getId());
linksensor.create();
}
else {
linksensor.setSensorFamilyId(sensorFam.getId());
linksensor.update();
}
Whereas the update works, the creation of the link does not work. Here is my code for the method "create":
#PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class SensorFamilySensorLink {
/** The id. */
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private long id;
/** The associated sensor id. */
#Persistent
private long sensorId;
/** The associated sensorFamily id. */
#Persistent
private long sensorFamilyId;
/**
* Create.
*/
public void create() {
PersistenceManager pm = PMF.getManager();
Transaction tx = pm.currentTransaction();
try {
tx.begin();
pm.makePersistent(this);
tx.commit();
} catch(Exception e) {
} finally {
if (tx.isActive()) {
tx.rollback(); // Error occurred so rollback the PM transaction
}
}
pm.close();
}
After debuggind, the problem comes from the generation if the IDs to use the SQL method INSERT in the table. THe generated id does not work when I am doing:
pm.makePersistent(this);
Is someone can say to me what I have forgotten because I have been searching for two days and I do not how to solve the problem? Besides, I use the same code for creating the sensor link with the system and the family link and it is working for the first one.
If you need more information, do not hesitate to ask me. Thanks in advance.
Related
Here , I want to hardcode some things into db at the action of server starts with Spring commandline runner
Problem :- In this I have checked that if 1L isn't present then do entry for that with Id 1L but still it stores to incremental Id when 1L or 2L or 3L is not present there.
My Entity In which I'm doing entry :-
Product Type
#Data
#Entity
#Table(name = "tbl_product_type_chemical")
public class ProductType implements IBaseData<Long> {
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Id
private Long id;
private String name;
#Column(columnDefinition = "text")
private String description;
}
This is method of Runner :-
private void loadProductTypeNew() throws Exception {
String SUBMODULE = " [Init Data] " + " [loadProductTypeNew()] ";
try {
ProductType fp = productTypeRepository.getOne(1L);
if (null == fp) {
fp = new ProductType();
fp.setId(1L);
fp.setName("FINISH PRODUCT");
productTypeRepository.save(fp);
}
ProductType rm = productTypeRepository.getOne(2L);
if (null != rm) {
rm = new ProductType();
rm.setId(2L);
rm.setName("RAW MATERIAL");
productTypeRepository.save(rm);
}
ProductType sm = productTypeRepository.getOne(3L);
if (null != sm) {
sm = new ProductType();
sm.setId(3L);
sm.setName("SUPPORTING MATERIAL");
productTypeRepository.save(sm);
}
} catch (Exception ex) {
ApplicationLogger.logger.error(SUBMODULE + ex.getMessage(), ex);
throw ex;
}
}
#Override
public void run(String... args) throws Exception {
loadProductTypeNew();`
}
Output :-
9 SUPPORTING MATERIAL
8 RAW MATERIAL
7 FINISH PRODUCT
10 FINISH PRODUCT
11 RAW MATERIAL
12 SUPPORTING MATERIAL
13 RAW MATERIAL
14 SUPPORTING MATERIAL
And I am calling it in run method.If anyone can solve thanks in advance
Nothing in your application should depend on specific values of the id field since it is generated by the database.
I suggest therefore to identify a business key (in your case the name), ensure it is unique with a primary key and use that to determine if a a row needs to be inserted in the database.
Your code would look similar to this
if (productTypeRepository.existsByName(""FINISH PRODUCT")) {
ProductType fp = new ProductType();
fp.setName("FINISH PRODUCT");
productTypeRepository.save(fp);
}
I am currently working on a web application which is basically a portfolio site for different vendors.
I was working on a thread which copies the details of a vendor and puts it against a new vendor, pretty straightforward.
The thread is intended to work fine but when selecting a particular Catalog object (this catalog object contains a Velocity template), the execution stops and it goes nowhere. Invoking the thread once again just hangs the whole application.
Here is my code.
public class CopySiteThread extends Thread {
public CopySiteThread(ComponentDTO componentDTO, long vendorid, int admin_id) {
/**Application specific business logic not exposed **/
}
public void run() {
/** Application based Business Logic Not Exposed **/
//Copy Catalog first
List<Catalog> catalog = catalogDAO.getCatalog(vendorid);
System.out.println(catalog);
List<Catalog> newCat = new ArrayList<Catalog>();
HashMap<String, Integer> catIdMapList = new HashMap<String, Integer>();
Iterator<Catalog> catIterator = catalog.iterator();
while (catIterator.hasNext()) {
Catalog cat = catIterator.next();
System.out.println(cat);
int catId = catalogDAO.addTemplate(admin_id, cat.getHtml(), cat.getName(), cat.getNickname(), cat.getTemplategroup(), vendor.getVendorid());
catIdMapList.put(cat.getName(), catId);
cat = null;
}
}
}
And the thread is invoked like this.
CopySiteThread thread = new CopySiteThread(componentDTO, baseVendor, admin_id);
thread.start();
After a certain number of iterations, it gets stuck on line Catalog cat = catIterator.next();
This issue is rather strange because I've developed many applications like this without any problem.
Any help appreciated.
The actual problem was in the addCatalog method in CatalogDAO
Session session = sf.openSession();
Transaction tx = null;
Integer templateID = null;
Date date = new Date();
try {
tx = session.beginTransaction();
Catalog catalog = new Catalog();
//Business Logic
templateID = (Integer) session.save(catalog);
} catch (HibernateException ex) {
if (tx != null) tx.rolback();
} finally {
session.close();
}
return templateID;
Fixed by adding a finally clause and closing all sessions.
I am using Google App Engine as a backend for my Android app.I am able to insert entities into the datastore using the method(auto-generated when i created the endpoint for my Note class)
/**
* This inserts a new entity into App Engine datastore. If the entity already
* exists in the datastore, an exception is thrown.
* It uses HTTP POST method.
*
* #param note the entity to be inserted.
* #return The inserted entity.
*/
#ApiMethod(name = "insertNote")
public Note insertNote(Note note) {
EntityManager mgr = getEntityManager();
try {
if (containsNote(note)) {
throw new EntityExistsException("Object already exists");
}
mgr.persist(note);
} finally {
mgr.close();
}
return note;
}
So to use this method from my Android app and insert an Entity i use this from my AsyncTask class
try {
Note note = new Note();
String descrptn = descriptionTF.getText().toString();
String email = emailTF.getText().toString();
String noteID = new Date().toString();
note.setDescription(descrptn);
note.setId(noteID);
note.setEmailAddress(email);
Note result = endpoint.insertNote(note).execute();
} catch (IOException e) {
e.printStackTrace();
}
It's all sunshine and rainbows till i try to retrieve the entity from the datastore.I get FATAL Exception:...Caused by Java.lang.NullPointerException: required parameter id must be specified
This is the method to call when trying to retrieve an Entity(Auto-generated also)
/**
* This method gets the entity having primary key id. It uses HTTP GET method.
*
* #param id the primary key of the java bean.
* #return The entity with primary key id.
*/
#ApiMethod(name = "getNote")
public Note getNote(#Named("id") String id) {
EntityManager mgr = getEntityManager();
Note note = null;
try {
note = mgr.find(Note.class, id);
} finally {
mgr.close();
}
return note;
}
and this is what am trying from my Android activity
try {
Note newNote = new Note();
String noteID = newNote.getId();
Note newResult = endpoint.getNote(noteID).execute();
String descrptn = newResult.getDescription();
String email = newResult.getEmailAddress();
descriptionTV.setText(descrptn);
emailTV.setText(email);
} catch (IOException e) {
e.printStackTrace();
}
return (long) 0;
}
Can any help me figure this out?
In your Android activity, I see the following code :
Note newNote = new Note();
String noteID = newNote.getId();
Note newResult = endpoint.getNote(noteID).execute();
If you see, you are creating an instance of the Note() class in the first line. This still means that other attributes of the Note class and which includes Id are null. So actually in your second line, you are assigning null to noteID and that is being passed along to the endpoint getNote method. Hence the server side gets a null for the Id and hence throws the exception.
In your Android code, you might be showing a list of notes in some ListActivity and then when you are selecting one of the notes, you will be able to get the ID from the selectedItem. So you should pass this value instead, to retrieve the details from the Server endpoint implementation.
Hope this makes things clear.
I am using JDO in GAE. I have two JDO classes having one to many relationship. parent class is
#PersistenceCapable(detachable="true")
#FetchGroup(name="childerns", members={#Persistent(name="aliasName")})
public class IdentityProvider {
#PrimaryKey
#Persistent
private String url;
#Persistent
private String domainName;
#Persistent
#Element(dependent = "true")
private ArrayList<AliasDomain> aliasName = new ArrayList<AliasDomain>();
}
The child classes is
#PersistenceCapable(detachable = "true")
public class AliasDomain {
#Persistent
private String url;
#Persistent
private String aliasName;
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
}
I am just performing CURD operations on both entity. First i create the parent instance and then i create the child instance as
public void addAliasDomain(AliasDomain domain) {
String url = domain.getUrl();
PersistenceManager pm = PMFSingleton.get().getPersistenceManager();
IdentityProvider idp = null;
Transaction txn = null;
try {
txn = pm.currentTransaction();
txn.begin();
pm.getFetchPlan().addGroup("childerns");
idp = pm.getObjectById(IdentityProvider.class, url);
idp = pm.detachCopy(idp);
idp.getAliasName().add(domain);
pm.makePersistent(idp);
txn.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
if ( txn.isActive() ) {
txn.rollback();
}
pm.close();
}
}
My issue is created when i delete any child instance. As you see from the above function i link the child to the parents( means add child object into arrayList). So when child is deleted its reference in the parents is not deleted so at the detached time of parents object i got exception which is as
Object of type "user.oauth.jdo.model.IdentityProvider" and identity "yahoo.com" was not detached correctly. Please consult the log for any possible information.
org.datanucleus.exceptions.NucleusUserException: Object of type "user.oauth.jdo.model.IdentityProvider" and identity "yahoo.com" was not detached correctly. Please consult the log for any possible information.
at org.datanucleus.state.JDOStateManager.detachCopy(JDOStateManager.java:2942)
at org.datanucleus.ObjectManagerImpl.detachObjectCopy(ObjectManagerImpl.java:2591)
at org.datanucleus.api.jdo.JDOPersistenceManager.jdoDetachCopy(JDOPersistenceManager.java:1145 )
at org.datanucleus.api.jdo.JDOPersistenceManager.detachCopy(JDOPersistenceManager.java:1174)
at user.oauth.data.broker.IDPJDOBroker.retrieveDomainList(IDPJDOBroker.java:49)
The code of function retreiveDomainList in IDPJDOBroker is
public List retrieveDomainList() {
PersistenceManager pm = PMFSingleton.get().getPersistenceManager();
Query query = pm.newQuery(IdentityProvider.class);
List<IdentityProvider> list = null;
List<IdentityProvider> detachedList = null;
IdentityProvider idp = null;
try {
pm.getFetchPlan().addGroup("childerns");
list = (List<IdentityProvider>) query.execute();
detachedList = new ArrayList<IdentityProvider>();
for(IdentityProvider obj : list){
idp = pm.detachCopy(obj);
OAuthJDOBroker broker = new OAuthJDOBroker();
int actUsers = 0;
if ( idp.getHistory() != null && idp.getHistory().size() > 0) {
actUsers = broker.calculateActiveUser(idp.getUserActiveDuration(),idp.getDomainName());
}
idp.setActiveUsers(actUsers);
detachedList.add(idp);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
query.closeAll();
pm.close();
}
return detachedList;
}
Please tell me what to do? Is it not possible in JDO to delete the child? if it is possible then how to do it properly.
I have just seen this, but in case anyone arrives here, to delete a child object in a one to many relationship you must delete the reference from the parent, the child object will be deleted "transparently"
I have a problem using GAEJ and JDO for storing the data.
This is what I'm working with:
class Usuari.java:
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
#Persistent
private String email;
#Persistent
private String rol="";
class DBUtils.java:
I've tried with two ways of doing the delete operation:
// This method removes a record from the database using its unique Key
public static boolean eliminar(Key k) throws Exception {
PersistenceManager pm = PMF.get().getPersistenceManager();
String kind;
Long id;
kind = k.getKind();
id = k.getId();
try {
if (k.getKind().equals("Usuari")) {
Usuari u = (Usuari)pm.getObjectById(k);
pm.deletePersistent(u);
_log.log(Level.INFO, "Deleted an entity->kind: " + kind + " id: " + id);
}
return true;
} catch (Exception e) {
_log.log(Level.SEVERE, "Unable to delete an entity->kind: " + kind + " id: " + id);
System.err.println(e.getMessage());
throw e;
}
finally {
pm.close();
}
}
// This method removes a record from the database using its unique Key - too
public static void eliminar2(Key k) throws Exception {
PersistenceManager pm = PMF.get().getPersistenceManager();
javax.jdo.Transaction tx = pm.currentTransaction();
try
{
tx.begin();
if (k.getKind().equals("Usuari")) {
Usuari u = (Usuari) pm.getObjectById(k);
pm.deletePersistent(u);
}
tx.commit();
}
catch (Exception e)
{
if (tx.isActive())
{
tx.rollback();
}
throw e;
}
}
I'm able to create new instances of some class "Usuari" but I can't delete them.
Everytime I call "eliminar" or "eliminar2" methods I get a "No such object" as result of trying to fetch it. I've checked manually and I see the object exists in my admin panel, with its ID and KIND, so I don't know what am I doing wrong.
Any help would be much appreciated.
PM.getObjectById does not take in a Key object, as per the JDO spec. It takes in an identity object, the same type as you would get from pm.getObjectId(obj); suggest you glance through the JDO spec. No doubt if you inspected what is returned from this method you would see that it can't find an object with that 'identity' because a Key is not an identity. You can also do
pm.getObjectById(Usuari.class, key);
which is shown very clearly in GAE documentation.
Still don't get why users are putting #Persistent on every field virtually every type is default persistent; only leads to making code more unreadable.