GWT RequestFactory: how to handle entities with composite primary keys - gwt

Can RequestFactory handle composite primary keys?
The documentation mentions that entities must implement getId(); how should this be implemented in the case where entities do not have a single "id" field, but rather have multiple foreign key fields that together constitute a composite primary key?

In GWT 2.1.1, the Id and Version properties may be of any type that RequestFactory knows how to transport. Basically, any primitive type (int), boxed type (Integer), or any object that has an associated Proxy type. You don't have to reduce a composite id to a String yourself; the RF plumbing can take care of composite keys automatically by using the persistent id of an entity-type key or the serialized state of a value-type key.
Using the previously-posted example:
interface Location {
public String getDepartment();
public String getDesk();
}
interface Employee {
public Location getId();
public int getVersion();
}
#ProxyFor(Location.class)
interface LocationProxy extends ValueProxy {
// ValueProxy means no requirement for getId() / getVersion()
String getDepartment();
String getDesk();
}
#ProxyFor(Employee.class)
interface EmployeeProxy extends EntityProxy {
// Use a composite type as an id key
LocationProxy getId();
// Version could also be a complex type
int getVersion();
}
If you can't reduce the identity to a single getId() property on the domain type, you can use a Locator to provide an externally-defined id and version property. For example:
#ProxyFor(value = Employee.class, locator = EmployeeLocator.class)
interface EmployeeProxy {.....}
class EmployeeLocator extends Locator<Employee, String> {
// There are several other methods to implement, too
String getId(Employee domainObject) { return domainObject.getDepartment() + " " + domainObject.getDesk(); }
}
The DevGuide linked from the question is a bit out of date with respect to
RequestFactory changes in 2.1.1

Related

Transactional not working with JPA saveAll

I'm trying to save a list of entity objects. Here is my method which is defined in a Service class:
#Transactional
public void creteEmployee(List<Employee> employeeList) {
employeeRepository.saveAll(employeeList);
}
And here is my JPA repository:
public interface EmployeeRepository extends PagingAndSortingRepository<Employee, Long> {
Page<Employee> findByCompany(Pageable pageable, Company company);
}
I've a unique constraint defined in my entity. If any item from the employeeList violates the unique constraint, I expect no one from the employeeList will be saved. Unfortunately all items except the problematic one is saved and also an DataIntegrityViolationException is raised. What should be done to make it atomic?

Override #Column attribute value

I have several POJOs which will have a monetary amount. My idea is to create a generic object MonetaryAmount (consisting of a currency and a value), which will then be used whenever I want to represent a monetary amount in one of my POJOs:
public class MonetaryAmount {
private String currency;
private BigDecimal value;
}
public class Account {
#Column(name = "ACCOUNT_NAME")
private String name;
private MonetaryAmount balance; // TODO set column annotation values of currency and value
}
Since MonetaryAmount will be used in several POJOs, I couldn't annotate the currency and value attributes with the #Column since the column name will not always be the same in all cases. Is there any way to annotate MonetaryAmount attributes (e.g. balance in the example above) to provide the column name for the currency and value attributes in a way that jOOQ understands them when mapping/unmapping a POJO similar to how Hibernate interprets the #AttributeOverride annotation please?
The #Embeddable annotation is currently (jOOQ 3.11) not supported by jOOQ's DefaultRecordMapper yet. The relevant feature requests are:
https://github.com/jOOQ/jOOQ/issues/2360
https://github.com/jOOQ/jOOQ/issues/2530
https://github.com/jOOQ/jOOQ/issues/6518
What you can do already now, if you're not using the JPA annotations on your POJOs, is to use the following aliasing notation in your query:
ctx.select(
ACCOUNT.ACCOUNT_NAME.as("name"),
ACCOUNT.CURRENCY.as("balance.currency"),
ACCOUNT.VALUE.as("balance.value"))
.from(ACCOUNT)
.fetchInto(Account.class);
This feature is documented in DefaultRecordMapper, see:
If Field.getName() is MY_field.MY_nested_field (case-sensitive!), then this field's value will be considered a nested value MY_nested_field, which is set on a nested POJO that is passed to all of these (regardless of visibility):
Single-argument instance method MY_field(...)
Single-argument instance method myField(...)
Single-argument instance method setMY_field(...)
Single-argument instance method setMyField(...)
Non-final instance member field MY_field
Non-final instance member field myField
Assuming Hibernate : You can used Embedded components.
#Entity
public class Account implements Serializable{
#Column(name = "ACCOUNT_NAME")
private String name;
#Embedded
#AttributeOverrides( {
    #AttributeOverride(name="currency", column = #Column(name="CURRENCY") ),
    #AttributeOverride(name="value", column = #Column(name="VALUE") )
} ) private MonetaryAmount balance;
}
#Embeddable
public class MonetaryAmount implements Serializable{
private String currency;
private BigDecimal value;
}
Though this should work, I think in your case you should try inheritance and still use same approach to override attributes in Object Oriented way.

JPA Generic Entity using Map

Is there a way to implement JPA Entity using Map? either extended HashMap or contain a hashmap i.e.:
#Entity
#Table(employee)
public class Employee {
/* .... */
void set(String columnName, Object columnValue) { /*...*/ }
Object get(String columnName) { /*...*/ }
}
and
#RepositoryRestResource
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
this way, there is no need to provide model attributes in the Employee class. Basically, whatever columns are defined in the database, it will be a property like entry in the Employee class.
Employee emp;
...
emp.get("name");
emp.get("id");
Is something like this possible?
Though not possible in vanilla JPA, EclipseLink dynamic entities (https://wiki.eclipse.org/EclipseLink/Examples/JPA/Dynamic) might be what you want. It allows for working with entities in a map-like fashion. Not sure if it is sufficient for your use case, though.

Generic Entity interface on gwt client side while using GwtQuery

I want to have a simple generic Entity interface pretty much like a map such as on client side in a Gwt + GwtQuery project .
public interface Entity extends JsonBuilder {
public String JsonObject getProperty(String property) ;
public Entity setProperty(String name , JsonObject obj ) ;
public String getPropertyType(String property) /* returns the actual
}
I want to be able to convert any pojo on server side to a Map form along with some type info and retrieve it on client as an Entity. Entities can be nested.
Is this doable ?
If yes. Please give some detailed guidelines.
To clarify further my goal is to have a single generic Entity interface that is capable of representing varied/diverse types of pojos from server. The type information of such a dynamic entity is expected to be available on the client side as a separate entity.
Do you think the code below will work and serve my purpose ? If yes - how will the json text underneath look like ?
public interface Tuple extends JsonBuilder {
public JsonValue get(String name);
public void set(String name, JsonValue ser);
}
public interface Entity extends Tuple {
public String getType();
public Tuple[] getTuples();
}

Entity Framework code first Inheritance Issue

I have code first implementation for flowing hierarchy,
BaseContact{
Public int Id{get;set;}
public string Name{get;set;}
//..
}
Person:BaseContact{
public string Designation{get;set;}
//..
}
Company:BaseContact{
public int NumOfEmployees{get;set;}
//..
}
I want to identify person or company with by using only the Id value? Currently I am using reflection to identify whether it is a person or company. Is there any other way to identify it without doing too much?
Without seeing how you initialised your classes I'm going to assume you have a table per concrete type approach.
You can't do it just from the ID, as you don't know which table the ID belongs to. ID 2 in "Person" table is a different entity to ID 3 in "Company". The only practical way to identify only from an ID is using a Table per Hierarchy approach and inspecting the type descriptor.
Some good references
http://weblogs.asp.net/manavi/archive/2011/01/03/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-3-table-per-concrete-type-tpc-and-choosing-strategy-guidelines.aspx
http://weblogs.asp.net/manavi/archive/2010/12/24/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-1-table-per-hierarchy-tph.aspx
You can also use a simple is statement instead of reflection. Ie if (entity is Company)
In your BaseContact (assume it is an abstract class) add abstract property which will be implemented by other two classes.Use Enum to identify the property type as follows.
public enum MyType
{
Person,
Company,
};
public abstract class BaseContact{
public abstract MyType ContactType{get;}
}
public class Person:BaseContact
{
public override MyType ContactType
{
get
{
return MyType.Person;
}
}
}
public class Company:BaseContact
{
public override MyType ContactType
{
get
{
return MyType.Company;
}
}
}
Use your BaseContact repository to retrieve entities and use enum for type separation.