I've created an entity with a pojo (ProductVariations) using the label #Serialize to be persisted in GAE through objectify:
#Entity
public class Product extends DatastoreObject{
//Reference without the colors and size information
#Index private String ref;
private double price;
private String details;
private String description;
#Serialize private ProductVariations pVariations;
private List<String> tags = new ArrayList<String>();
//Getters & Setters
}
The problem is that I don't see how to access my pojo with requestfactory because ProductVariations is not a domain type.
In any other case I would use an embeded object but in this particular case I have a nested collection inside ProductVariations witch is a collection in itself (ProductVariations extends ArrayList).
Any suggestions in how to achieve this?
Thank you.
Not sure I understand your question, but you need to implement Serializable in Product if you want to send it over RPC.
Beyond that, are you having problems storing ProductVariations? It's an interesting concept. If it isn't working:
Can you keep ProductVariations in its own #Entity?
Then keep a Key in Product class (or a Long that can you can create a Key from).
For convenience you can also leave ProductVariations in Product but mark it with #Transient and then populate it from the Key/Long in the factory that does your ofy.get().
Related
I'm struggling to write this, so I may have to give an example to help explain the problem I'm experiencing.
Say we have nodes of three types (these nodes may have more relationships of their own, e.g. Product Family, has product manager):
Product
Product Family
Battery
With these relationships
A product can be be in 0 or more families
A product can have 0 or more batteries.
When using spring-data-neo4j and saving a new Product, I wish to include these relatiopnships, such as the batteries they require and the product family they belong to. However if I only supply say an ID rather then a fully populated object, it overwrites this object along with properties and relations accordingly.
This isn't great as it means that I have to end up sending a fully populated object, with all it's relations everytime I wish to save something, and some of these relations may go quite deep.
My domain is as follows:
#Node
public class Product {
#Id
#GeneratedValue(generatorClass = SnowflakeGenerator.class)
private Long productId;
private String name;
#Relationship(type = "REQUIRES_BATTERY", direction = OUTGOING)
private List<Battery> batteryList;
#Relationship(type = "IN_FAMILY", direction = OUTGOING)
private List<ProductFamily> productFamilyList;
}
#Node
public class Battery {
#Id
#GeneratedValue(generatorClass = SnowflakeGenerator.class)
private Long batteryId;
private String name;
}
#Node
public class ProductFamily {
#Id
#GeneratedValue(generatorClass = SnowflakeGenerator.class)
private Long familyId;
private String name;
}
This could very well by from coming from a Relational Database mindset and is a 'limitation' of using Neo4J.
TLDR When persisting somethign in Neo4J using spring-data how can I save just a relationship, rather than a whole related Node.
You can make use of projections in Spring Data Neo4j. (https://docs.spring.io/spring-data/neo4j/docs/current/reference/html/#projections)
This gives you the option to put a "mask" on the object tree, you want to persist (and what should stay untouched).
For example in your case:
interface ProductProjection {
// without defining e.g. String getName() here, SDN would not ever touch this property.
List<BatteryProjection> getBatteryList();
List<ProductFamilyProjection> getProductFamilyList();
}
interface BatteryProjection {
String getName();
}
interface ProductFamilyProjection {
String getName();
}
I am trying to figure it out how to do this proper way. Let's say I have entity Employee like that:
#Entity
public class EmployeeEntity{
#Id
private Long id;
private String username;
private String password;
private List<AddressEntity> addresses;
private DepartmentEntity department;
}
Now let's say some AddressEntity and DepartmentEntity are already created so I just want to point it. Controller would look like this:
#RestController
public class EmployeeController{
#Autowired
private EmployeeService;
#PostMapping
public EmployeeDto createEmployee(#RequestBody EmployeeDto employee){
return employeeService.createEmployee(employee);
}
}
And DTO:
public class EmployeeDto{
private Long id;
private String username;
private String password;
private List<AddressDto> addresses;
// private List<Long> addressesIds;
private DepartmentDto department;
// private Long departmentId;
}
So what bothers me is how properly transfer data from request to service layer and to response.
should DTO be object 1:1 same like entity?
or with additional values, like ids of others related objects?
or DTO is just concept and as well I can use custom request/response for every occasion? This would be handy but is it the way it should be done? There would be plenty of one-case-use classes.
Crating new entity is first problem but how about updating? If I would like to update just Employee username, I shouldn`t pass all rest of the objects so ids maybe? And it should be custom UpdateEmployeeRequest with only updatable fields or DTO with all data like password?
Sorry if I messed up a little. Too much new knowledge and I feel like I go round and round like a child in the fog...
should DTO be object 1:1 same like entity? or with additional values, like ids of others related objects?
Not necessary. DTOs are mostly to pass data to view layer. You can wrap data from multiple entities and send in one DTO to view.
or DTO is just concept and as well I can use custom request/response for every occasion? This would be handy but is it the way it should be done? There would be plenty of one-case-use classes.
Yes. It is like custom request/response for every occasion (data transfer to view and from view).
Crating new entity is first problem but how about updating? If I would like to update just Employee username, I shouldn`t pass all rest of the objects so ids maybe? And it should be custom UpdateEmployeeRequest with only updatable fields or DTO with all data like password?
Pass the required minimum fields and use same DTO on Create/Update (Id with field to update on update and other fields on Create).
Example dto for create:
username : "some user",
password : "some password",
... other fields
Example JSON for update username:
id: 1,
username : "some user",
I have two objects with name Site and AppSite, both has same fields like below. Is there any util class to copy all the fields from AppSite to Site, like BeanUtils.copyProperties.
public class AmsSite implements Serializable{
private long siteId;
private String name;
private String routingId;
private String siteType;
private List<AmsPlatform> platforms;
private List<AmsProvider> providers;
public class Site implements Serializable{
private long siteId;
private String name;
private String routingId;
private String siteType;
private List<Platform> platforms;
private List<Provider> providers;
If you see in above two pojo, i have two list of object fields. Both that object also same like Site and AmsSite object only. Has same field name but different class name.
BeanUtils.copyProperties is copying all the literal field values from AppSite to Site properly, but not the inner object. (I mean deep copy is not happening). I saw Serialization.clone in apache common lang works for deep copy, but that works only if we have same class name. My case is bit different same field name but different class name.
You could try an object mapper like Orika but I'm not sure if it will work with inner classes.
If you have a lot of these type of objects you might want to consider restructuring your objects to fit an easier pattern.
I'm questioning the way that I have been designing my JavaBeans. For example, say I have the following:
Employee - basic employee information:
private String employee_id;
private String first_name;
private String last_name;
private String phone;
private String deptNo;
etc..
WorkflowPlayer - details about an employee in a system workflow:
private String workflow_instance_id;
private String employee_id;
private String role_class_id;
private String role_required;
private Employee employee;
private RoleClass roleClass;
RoleClass - details of a type of role (Approver, SecurityReviewer, Originator, Instructor, Manager, etc..)
private String role_class_id;
private String name;
private String label;
private String description;
These three models also correspond directly to Database tables (Employee is a read only view for me, if that matters)
Then in my view I would do something like
workflow_player.employee.first_name
workflow_player.roleClass.label
Is it acceptable to make Employee an instance variable? Or should I instead be extending WorkflowPlayer with Employee and then do
workflow_player.first_name
this makes sense for employee but not for roleClass.
workflow_player.description //NO!
I just want to use a consistent [correct] pattern
Yes, it's ok to make Employee an instance variable if you are referring to it from another table. Subclassing in this case is wrong because from your description it sounds like workflow is not a specialized kind of employee. Ask yourself if the lifecycles of these entities are the same or different, and if the subclass is substitutable for the superclass in all situations.
Subclassing should be a last resort reserved for cases where some entity is a specialized version of another entity and you want to refer to the specialized versions by their superclass.
There are specific patterns where subclassing is used in Object-relational mapping: table per class hierarchy, table per subclass, table per concrete entity, etc. The Hibernate documentation describes them. You would use inheritance in mapping objects to tables when your tables fall into one of those patterns. Even if you're not using Hibernate that's still a good example to follow.
I think role classes are a great design approach, and many developers do not use them. This matches the canonical use of role classes: when an entity participates in different activities, and within those activities, the view of that type is different. A good example would be the following. Suppose we were modeling payroll. We have a user who is both one of the employees who is getting paid, and an administrator in the app. In Java, we would have to model that as role classes because we don't have multiple inheritance, but it's really a more accurate representation because the role class, if it does confer any additional behavior or properties, it is doing so in the context of its own behavior. So for instance, whatever powers you need to grant the administrator in the payroll is confined to that realm.
It's also not an either/or situation: in the Payroll, you might want to show that some employees are also managers. That probably would best be done with inheritance, but the role class is still valid, again, as a way of representing participation.
You can't map JavaBean directly to Tables, because OO is not the same as Relational (Database).
You could use an ORM, like Hibernate, to map you JavaBean to SGBD Tables properly.
From an OO point of view, beans should be like that
public class Employee {
private String id;
private String firstName;
private String lastName;
private String phone;
private String deptNo;
}
public class WorkflowPlayer {
private String id;
private String roleRequired;
private Employee employee;
private Role roleClass;
}
public class RoleClass {
private String id;
private String name;
private String label;
private String description;
}
I am building an application which allows restaurant guests to order food and send to server.
What i have considered is to
1) create a class Order.java class
public class Order
{
private Intger tableId;
private Integer restaurantId;
private Integer foodId;
private Integer foodQuantity;
getter and setters
}
2) This class object will be populated with guests order and an ArrayList of objects of the class will be sent to server as Gson String.
Now if an order consist of some 7 items, Then the arraylist will have 7 objects, but tableId and restaurantId will be same 7 times.
can you suggest a better design where in I can associate restaurantId and tableId with the entire arraylist.
Thanks.
There is no right solution, it would depend on your needs, one possible solution would be something like:
public class Order {
private int tableId;
private int restaurant;
private List<OrderItem> items;
// setters and getters
}
public class OrderItem {
private int itemId; // foodId
private int quatity; // foodQuantity
// setters and getters
}
But if you were in a situation that the information comes not normalized, like you suggested (in which tableId is repeated for every single food ordered), I would consider to implement a normalization process that will return a structure with the classes I draft above. But if you are implementing it, please consider to make it as normalized as possible.