Accessing Roo Identifier - jpa

I have this entity class having more than one primary key (#Id) which resulted me to use #RooJpaActiveRecord(identifierType = '<IdentifierClass.class>') and #RooIdentifier(dbManaged=true). Yet I am having a problem on accessing Identifier.class from the entity class itself.
My questions is how can I access Identifier in the entity class without, at most, removing the #RooJpaActiveRecord(identifierType = '<Identifier.class>') code.

Roo will generate a property id on your entity. This property is declared on MyEntity_Roo_Jpa_Entity.aj file (this includes a getter/setter). So, you simple use:
MyEntity myEntity = new MyEntity();
myEntity.setId(new Identifier());
myEntity.getId().setPk1(value1);
// ....
// ....
myEntity.getId().setPkn(valuen);

Related

entityframework clone or copy an entity instance to another object

I am working on an asp.net mvc core 2.0 project and entityframework.
I am working with viewmodel concept.
This mean i do not pass entities instances directly to my view, i pass a viewmodel instance which only contains what the view needs.
in one case, i need to pass the entire entity fields plus other informations.
What i've done is a derivated my ViewModel class from my Entity Class. and i add the extra fields:
public MyViewModel: Person
{
// I will automaticly have Person fields in MyViewModel
public bool IsSelected {get;set;}
public String otherinformation {get;set;}
...
}
I am fed up with assigning each fields of my viewmodel from my entity instance.
myviewmodelinstance.field1 = myentity.field1;
myviewmodelinstance.field2 = myentity.field2;
myviewmodelinstance.field3 = myentity.field3;
myviewmodelinstance.IsSelected = false;
...
And i need to do the inverse operation in the postback.
Is there a way to "copy" or "clone" every fields, like this:
myentity.CopyTo(myviewmodelinstance);
myviewmodelinstance.IsSelected = false;
Thanks
You could use the AutoMapper to achieve it. It is the ideal way to perform it. Another option is that you can serialize and deseriliaze the object as json.
var myviewmodelinstance = JsonConvert.DeserializeObject<MyViewModel>(JsonConvert.SerializeObject(myentity));
Note : The code I provided required Json.Net

JPA Inheritance - Change the Entity type

I have two classes
#Entity
#Inheritance(strategy=InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name="PERSONTYPE")
#DiscriminatorValue(value="PERSON")
public class Parent {
.......
}
#Entity
#DiscriminatorValue(value="CHILD")
public class Child extends Parent{
.......
}
The scenario I have:
create a person -- then the PERSONTYPE = 'PERSON'
go the Person page and update it to be 'CHILD' by checking a check box 'Is Child' then after save the Person must be saved to be with type 'CHILD'.
Then how can I change the entity type from 'PERSON' to 'CHILD'?
Here are a couple possibilities:
It seems the obvious thing to do would be to setIsChild(true) on the Parent object and commit it, however I'm not sure how JPA will react to this since you are now committing a Parent and the result is a Child. Not sure this is possible. It is definitely worth a try.
Another option would be to write JPA update statement (circumventing Child and Parent objects) to update the is_child column in the database. Then when you subsequently query this record you will get a Child back not a Parent.
Lastly, you could create a child object with all values of the parent object, then delete the parent, and create the child. This will work, however aside from the extra processing required for delete / create, instead of a simple update, the id of the child may change (it will change if you are using auto generated ids). IMO, this is not a good solution, but it will work.
i assume you have unique properties for Child Object and thats why you want to use inheritance, otherwize just as #ZB Ziet commented you should just use child flag
Solution 1
i see you are using single table inheritance strategy, thus you have to modify the descriminator field manulay (by using SQL queries) and set appropirate fields on child table.
UPDATE Parent SET PERSONTYPE='CHILD' WHERE id = 1
practicaly you use native queries like this
enityManager.createNativeQuery(“UPDATE PERSON SET PERSONTYPE = ?, ”
“ VERSION = VERSION + 1 WHERE ID = ?”)
.setParameter(1, 'CHILD')
.setParameter(2,personID)
.executeUpdate();
then you can use entitymanager to get the child and set properties
entityManager.find(Child.class,1).childProp=xxxx
** Solution 2 **
IMO, The best thing to do here is instead of using single table strategy you should use joined table strategy
in joined table strategy new table entireis is created for each child having thier id as foreign key to parent entity.so changing the id will also set its parent
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public class Person {
...
it would have been cool if you can just create new child set the id same as parent and save. Child c = new Child(); c.setId(parent.getId()); entityManager.merge(c) . but hibernate tries to re-create a parent object resulting id confilict.
so the solution is to write native query
em.createNativeQuery("INSERT into child (id) VALUES (1)").executeUpdate(); //1 being the parent id
more reference on inheritance
Use EntityMaster
The Idea is to create an Entity just for changing the discriminator.
At least this Entity need to have the id and the discriminator.
#Entity
public class ParentMaster {
public static final PERSON="PERSON";
public static final CHILD="CHILD";
private Long id;
private String persontype;
//getter setter
}
Now load the ParentMaster by id and pm.setPersontype(ParentMaster.CHILD);.

greenDao generator is not generating certain variables in auto generated classes

Below is my schema generation code, Two variables (storeIdForSurvey & questionIdForAnswer) are not being auto generated in the model class( Survey & Question), though they are present the in auto generated dao classes (SurveyDao & QuestionDao).
Object Oriented description of the domain is as : User has Store, Store has Survey,Survey has FollowupItems, Survey has Category, Category has Question, Question has History, Question has Answer.
private static void addUser(Schema schema) {
//User
Entity user = schema.addEntity("User");
user.addIdProperty();
user.addStringProperty("districtId");
user.addStringProperty("employeeId");
user.addStringProperty("name");
user.addStringProperty("sessionToken");
user.addStringProperty("userId");
//Store
Entity store = schema.addEntity("Store");
// foreign key
Property userIdForStore = store.addLongProperty("userIdForStore").getProperty();
store.addToOne(user, userIdForStore);
user.addToMany(store, userIdForStore);
store.addIdProperty();
store.addStringProperty("storeId");
store.addStringProperty("address");
store.addStringProperty("city");
store.addStringProperty("storeName");
store.addStringProperty("state");
store.addStringProperty("zip");
store.addStringProperty("storeManagerName");
store.addBooleanProperty("isSurveyHistoryAvailable");
//Survey
Entity survey = schema.addEntity("Survey");
//foreign key
Property storeIdForSurvey = survey.addLongProperty("storeIdForSurvey").getProperty();
survey.addToOne(store, storeIdForSurvey); // one store can have one survey at a time
store.addToOne(survey, storeIdForSurvey);
survey.addIdProperty();
survey.addStringProperty("surveyId");
survey.addStringProperty("dmSignImagePath");
survey.addStringProperty("dmSignImageName");
survey.addStringProperty("smSignImagePath");
survey.addStringProperty("smSignImageName");
survey.addStringProperty("startlatitude");
survey.addStringProperty("startlongitude");
survey.addStringProperty("submitLatitude");
survey.addStringProperty("submitLongitude");
survey.addStringProperty("acknowledgedBy");
survey.addStringProperty("deliveredBy");
survey.addStringProperty("name");
survey.addStringProperty("createdBy");
survey.addStringProperty("description");
survey.addStringProperty("storeId");
survey.addStringProperty("districtManager");
survey.addDateProperty("startDate");
survey.addDateProperty("submitDate");
survey.addDateProperty("syncDate");
survey.addDateProperty("createdDate");
survey.addDateProperty("actionItemAssignDate");
survey.addDateProperty("actionItemDueDate");
survey.addDoubleProperty("score");
//FolloupItems
Entity followupItem = schema.addEntity("FollowupItem");
//foreign key
Property surveyIdForFollowupItem = followupItem.addLongProperty("surveyIdForFollowupItem").getProperty();
followupItem.addToOne(survey, surveyIdForFollowupItem);
survey.addToMany(followupItem, surveyIdForFollowupItem);
followupItem.addIdProperty();
followupItem.addStringProperty("assignedTo");
followupItem.addStringProperty("comment");
followupItem.addStringProperty("photoName");
followupItem.addStringProperty("photoURL");
followupItem.addDateProperty("assignedDate");
followupItem.addDateProperty("dueDate");
followupItem.addDateProperty("expeireDate");
//Category
Entity category = schema.addEntity("Category");
//foreign key
Property surveyIdForCategory = category.addLongProperty("surveyIdForCategory").getProperty();
category.addToOne(survey, surveyIdForCategory);
survey.addToMany(category, surveyIdForCategory);
category.addIdProperty();
category.addStringProperty("categoryId");
category.addStringProperty("name");
category.addStringProperty("weight");
category.addStringProperty("surveyId");
category.addDoubleProperty("totalScore");
category.addIntProperty("sortOrder");
category.addBooleanProperty("completionStatus");
category.addBooleanProperty("hasActionItem");
//Question
Entity question = schema.addEntity("Question");
//foreign key
Property categoryIdForQuestion = question.addLongProperty("categoryIdForQuestion").getProperty();
question.addToOne(category, categoryIdForQuestion);
category.addToMany(question, categoryIdForQuestion);
question.addIdProperty();
question.addStringProperty("questionId");
question.addDateProperty("startDate");
question.addDateProperty("endDate");
question.addStringProperty("statement");
question.addStringProperty("type");
question.addStringProperty("weight");
question.addStringProperty("surveyCategoryName");
question.addIntProperty("displayOrder");
question.addBooleanProperty("naFlag");
question.addBooleanProperty("isRequired");
//Question History
Entity questionHistory = schema.addEntity("questionHistory");
//foreign key
Property questionIdForQuestionHistory = questionHistory.addLongProperty("questionIdForQuestionHistory").getProperty();
questionHistory.addToOne(store, questionIdForQuestionHistory);
question.addToMany(questionHistory, questionIdForQuestionHistory);
questionHistory.addIdProperty();
questionHistory.addStringProperty("questionId");
questionHistory.addStringProperty("secondLastHistory");
questionHistory.addStringProperty("lastHistory");
//Answer
Entity answer = schema.addEntity("Answer");
//foreign key
Property questionIdForAnswer = answer.addLongProperty("questionIdForAnswer").getProperty();
question.addToOne(answer, questionIdForAnswer);
answer.addToOne(question, questionIdForAnswer);
answer.addIdProperty();
answer.addStringProperty("projectType");
answer.addStringProperty("assignedTo");
answer.addStringProperty("comment");
answer.addStringProperty("photoUrl");
answer.addStringProperty("photoNmae");
answer.addStringProperty("selectedOption");
answer.addDateProperty("assignedDate");
answer.addDateProperty("dueDate");
answer.addDateProperty("expireDate");
answer.addDoubleProperty("score");
}
please read the documentation carefully:
public ToOne addToOne(Entity target, Property fkProperty)
Adds a to-one relationship to the given target entity using the given given
foreign key property (which belongs to this entity).
This means the following statement is correct:
Property storeIdForSurvey = survey.addLongProperty("storeIdForSurvey").getProperty();
survey.addToOne(store, storeIdForSurvey);
but the next statement is incorrect since the Property storeIdForSurvey is not member of the Entity store:
store.addToOne(survey, storeIdForSurvey);
Try to use this statement instead:
store.addToOneWithoutProperty("Survey", survey, "storeIdForSurvey");

1-n relations and EntityKey with EntityFramework

When I have an entity that holds a reference to a singular entity I can create an EntityKey and assign that value to the EntityNameReference.Value property. It works perfectly and like a charm.
If I have an entity that holds a reference to multiple entities I cannot succeed in doing the same thing. Suppose an entity called Application that has a property that contains references to Modules (so Application has a List property called Modules).
How can I programmatically attach entity keys to that kind of property?
I tried something like this, without any success:
foreach(int idModule in selectedModules)
{
Module m = new Module();
m.EntityKey = new EntityKey("myModel.ModuleSet", "idModule", idModule);
ctx.Attach(m); //Here I have an exception
app.Modules.Add(m);
Thanks a lot for your help.
Marco
Does Module have Application navigation property? It should.
I would write something like:
foreach(int idModule in selectedModules)
{
Module m = new Module();
m.EntityKey = new EntityKey("myModel.ModuleSet", "idModule", idModule);
m.Application = app;
app.Modules.Add(m);
}
ctx.SaveChanges();

How to relate entities that are not directly mapped through a navigation property

I have an object that has been populated with the contents of four different related entities. However i have another entity in which i cannot include as part of the query due to it not being related in the navigation properites directly to the IQueryable table i am pulling. The entity i am trying to include is related to one of the four different entities that have been included successfully.
Is there a way to include(during db hit or afterwards) this entity as part of the overall object i am creating?
Here is an example of what my calls look like to build the CARTITEM object:
public List<CARTITEM> ListCartItem(Guid cartId)
{
//Create the Entity object
List<CARTITEM> itemInfo = null;
using (Entities webStoreContext = new Entities())
{
//Invoke the query
itemInfo = WebStoreDelegates.selectCartItems.Invoke(webStoreContext).ByCartID(cartId).ToList();
}
//Return the result set
return itemInfo;
}
here is the selectCartItems filter(Where i would normally do the includes):
public static Func<Entities, IQueryable<CARTITEM>> selectCartItems =
CompiledQuery.Compile<Entities, IQueryable<CARTITEM>>(
(cart) => from c in cart.CARTITEM.Include("ITEM").Include("SHIPPINGOPTION").Include("RELATEDITEM").Include("PROMOTION")
select c);
from this i have my CARTITEM object. Problem is i want to include the PROMOTIONTYPE table in this object, but since the CARTIEM entity doesn't have a navigation property directly to the PROMOTIONTYPE table i get an error.
Let me know if you need any more clarification.
Thanks,
Billy
You can use join and if it is the same database and server it should generate the join in SQL and do it all in one call...
LinqToEnties join example