I'm creating a heirarchy of classes for the purposes of denormalizing a table. Tables are quite wide so to manage hassle and errors, I would like to declare all fields in the parent and then alter the definition of specific fields in the child. This way I can have a normal column in the parent be redefined as part of a primary key in the child.
E.g.:
Basic super-class
public class A {
#Column
protected int age;
}
Class extending A
#Table
public class B extends A {
#PrimaryKey
protected K key;
...
}
Primary key for A, with a new definition of the age column.
#PrimaryKeyClass
public class K {
#PrimaryKeyColumn
private int age;
#PrimaryKeyColumn
private int ignore;
}
That doesn't seem to work. I get a Multiple definition of identifier exception.
So far I can only declare fields that won't change in the parent and then declare all possibly-changing fields in each child. I don't like this because I have to know upfront every field that might become part of future primary keys.
Putting the annotations on the (parent) getters and overriding those doesn't seem to have done anything.
Any way to solve this aside from keeping only never-changing columns in the parent?
Putting the annotations on the (parent) getters and overriding those doesn't seem to have done anything.
Annotating the child getters with #Transient did!
So: annotate the parent getters rather than the fields, make child getters #Transient, move column definition into the key, done.
From here:
http://docs.datastax.com/en/developer/java-driver/3.1/manual/object_mapper/creating/
One powerful advantage of annotating getter methods is that annotations are inherited from overridden methods in superclasses and superinterfaces; in other words, if a getter method is overridden in a subclass, annotations in both method declarations will get merged together. If duplicated annotations are found during this merge process, the overriding method’s annotations will take precedence over the overridden’s.
Related
I'm not really sure about how to distinguish whether I should define a relationship as dependency or association for certain cases.
For example,
class AttendanceSheet {
Map<String> students;
boolean[] attend;
public void addStudent(Student s)
{
students.add(s.getName(),s.getStudentNumber());
}
public void checkAttendance(String name) { //... }
}
class Student {
private String name;
private int staffNumber;
//more information such as address, age, etc..
Student(String n, int sn)
{
name = n;
studentNumber = sn;
}
public String getName()
{
return name.clone();
}
public String getStudentNumber()
{
return studentNumber;
}
}
For this case, would Student and Association have association or dependency?
This is because I'm not sure whether the association must have the actual reference of the object or it suffice to just have certain information that can reach the object (since student id and number is far more enough to know find out which student object it is directing to).
In your case the <<uses>> is sufficient, because you don't have actual properties of type Student in AttendanceSheet.
As a side note: not using object references and instead just having the studentNumber is - to say the least - an odd design. But I don't know the context.
On the business level those objects are related, but there is no single preferred method of diagramming this relationship.
Please see Section 9.5.4 of UML specification for more details on the topic, especially Figure 9.12
To be specific those two notations are semantically equivalent (I'm ignoring irrelevant details):
In the first one to keep a traceability you can use an explicit Dependency pretty much the way you did.
One can also consider students as a Shared Aggregation, however it might be also considered an overkill. Not necessary, just showing a possibility for an answer completeness.
You may also consider Qulified associations to indicate a reference to the Student is based on their specific properties. This is pretty much closest to your need. Sorry, I don't know how to achieve such notation in my tool, but you can find more details in Figure 11.37 in Section 11.5 of the aforementioned specification.
I am using Nomin for mapping tasks. As taken from the documentation of Nomin it should be able to map fields with the same name by itself in case automapping has been activated. When activating it, it causes an infinite loop exception.
I have the following:
mappingFor a: CoinsOnMarketPlace, b: Coin
// automap() // when deactivated it works fine, when activated infinite loop
a.coin.name = b.name
a.coin.rank = b.rank
a.priceUSD = b.priceUSD // Could be automapped
a.priceBTC = b.priceBTC // Could be automapped
...
Exception:
org.nomin.core.NominException: ./net/hemisoft/ccm/repository/coinmarketcap2coin.groovy: Recursive mapping rule a = b causes infinite loop!
One thing worth adding regarding your use case - this Recursive mapping rule a = b causes infinite loop! exception is thrown because you use groovy classes in your mapping rule. Nomin uses ReflectionIntrospector and what's important:
It performs getting/setting properties using accessor methods which are called through the Java reflection mechanism. ReflectionIntrospector uses supplied NamingPolicy instance to determine accessor methods. JbNamingPolicy is used by default, this implementation cerresponds the JavaBeans convention. Its InstanceCreator named ReflectionInstanceCreator instantiates objects using Class.newInstance().
Source: http://nomin.sourceforge.net/introspectors.html
A simple Groovy class like:
class Entity {
String name
String somethingElse
}
gets compiled to a Java class that implements GroovyObject providing following methods:
public interface GroovyObject {
Object invokeMethod(String var1, Object var2);
Object getProperty(String var1);
void setProperty(String var1, Object var2);
MetaClass getMetaClass();
void setMetaClass(MetaClass var1);
}
In this case ReflectionInstanceCreator combined with automap() resolves following mappings:
a.property = b.property
and
a = b
where a = b mapping comes from MetaClass getMetaClass() getter method I suppose, because there is no mapping like a.metaClass = b.metaClass resolved. a.property = b.property gets resolved because of Object getProperty(String var1) method.
Solution
This problem can be solved by specifying explicitly ExplodingIntrospector for your mapping script that:
It performs getting/setting properties using a class field immediately through through the Java reflection mechanism and may be useful in case when domain object don't provide accessors for their properties. Supplied instance creator is ReflectionInstanceCreator.
Source: http://nomin.sourceforge.net/introspectors.html
All you have to do is to add
introspector exploding
right below mappingFor a: ..., b: ... header. For example:
import mypackage.Entity
import mypackage.EntityDto
mappingFor a: Entity, b: EntityDto
introspector exploding
automap()
a.test2 = b.test1
Tested with two Groovy classes, worked like a charm. Hope it helps.
There may be situations where we need to return a list of tuple rows from the associated data model i.e not a fully qualified entity but a part of it, specifically a list of selected columns from the associated data-source (may be a database).
I know of some of ways to return a list of tuple rows from the database using JPA like the following
There is no need to look closely into the code from the JPA criteria API, if you were to dislike criteria queries. The question is not directly related to JPA criteria. I prefer JPA criteria to JPQL for no precise reason - just because I like criteria queries very much.
Using a list of object arrays - List<Object[]> :
public List<Object[]> object(int first, int pageSize) {
CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery<Object[]>criteriaQuery=criteriaBuilder.createQuery(Object[].class);
Root<Product> root = criteriaQuery.from(entityManager.getMetamodel().entity(Product.class));
List<Selection<?>>selections=new ArrayList<Selection<?>>();
selections.add(root.get(Product_.prodId));
selections.add(root.get(Product_.prodName));
selections.add(root.get(Product_.prodCode));
selections.add(root.get(Product_.prodDesc));
selections.add(root.get(Product_.marketPrice));
selections.add(root.get(Product_.salePrice));
criteriaQuery.select(criteriaBuilder.array(selections.toArray(new Selection[0])));
//Or criteriaQuery.multiselect(selections.toArray(new Selection[0]));
return entityManager.createQuery(criteriaQuery).setFirstResult(first).setMaxResults(pageSize).getResultList();
}
Using a list of tuples - List<Tuple> :
public List<Tuple> tuple(int first, int pageSize) {
CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery<Tuple>criteriaQuery=criteriaBuilder.createTupleQuery();
Root<Product> root = criteriaQuery.from(entityManager.getMetamodel().entity(Product.class));
List<Selection<?>>selections=new ArrayList<Selection<?>>();
selections.add(root.get(Product_.prodId));
selections.add(root.get(Product_.prodName));
selections.add(root.get(Product_.prodCode));
selections.add(root.get(Product_.prodDesc));
selections.add(root.get(Product_.marketPrice));
selections.add(root.get(Product_.salePrice));
criteriaQuery.select(criteriaBuilder.tuple(selections.toArray(new Selection[0])));
//Or criteriaQuery.multiselect(selections.toArray(new Selection[0]));
return entityManager.createQuery(criteriaQuery).setFirstResult(first).setMaxResults(pageSize).getResultList();
}
Using a list of rows mapped a class of objects - List<MappedClass> :
public List<ProductUtils> constructor(int first, int pageSize) {
CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery<ProductUtils>criteriaQuery=criteriaBuilder.createQuery(ProductUtils.class);
Root<Product> root = criteriaQuery.from(entityManager.getMetamodel().entity(Product.class));
List<Selection<?>>selections=new ArrayList<Selection<?>>();
selections.add(root.get(Product_.prodId));
selections.add(root.get(Product_.prodName));
selections.add(root.get(Product_.prodCode));
selections.add(root.get(Product_.prodDesc));
selections.add(root.get(Product_.marketPrice));
selections.add(root.get(Product_.salePrice));
criteriaQuery.select(criteriaBuilder.construct(ProductUtils.class, selections.toArray(new Selection[0])));
//Or criteriaQuery.multiselect(selections.toArray(new Selection[0]));
return entityManager.createQuery(criteriaQuery).setFirstResult(first).setMaxResults(pageSize).getResultList();
}
Again the same thing can be rewritten using JPQL.
The first two of them are ugly and require accessing properties using indices in EL on XHTML pages. Maintaining them is difficult, if the order in which the fields appear is changed at a later time (of course, aliases can be used with Tuple). Also, use of Tuple is always avoidable, since it requires an additional dependency in JSF from the javax.persistence package increasing coupling between modules.
Using a constructor query to map the result list to a class may suffice. It can be used along with PrimeFaces LazyDataModel as follows.
#Named
#ViewScoped
public class TestManagedBean extends LazyDataModel<ProductUtils> implements Serializable {
#Inject
private Service service;
private static final long serialVersionUID=1L;
public TestManagedBean() {}
#Override
public List<ProductUtils> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String, Object> filters) {
// Put some logic here like setting total rows for LazyDataModel - setRowCount(10)
return service.constructor(first, pageSize); //Use filters and sort meta whenever necessary.
}
}
But this is also too unmaintainable, if I need to access more or less fields from the database at some later time at a different place that requires creating a new class or adding a new constructor (constructor overloading in the existing class) to the existing class which in turn requires to check carefully the actual and formal parameters of the constructor method to see, if they match in number, order and type precisely that often makes me blind.
I hope, there should be some better ways that allow us to tackle such situations in a precise way.
Parameterized constructor(s) in the existing entity classes, if used instead (without creating a new class like ProductUtils, in this case) may cause problems while implementing web services (JAX-WS) in the application (if needed). Therefore, I never tend to use parameterized constructors of entity classes anywhere.
I'm supposed to declare a class field for a federal tax rate, which is a constant, with a value .07. How can I achieve this?
Since you didn't specify a language, I'll throw in a Java solution
public class YourClass {
public static final double TAX_RATE = 0.07;
}
In Java naming convention, you name your constants with all upper casing and use _ to separate words instead of the normal camel casing.
the final keyword, is to make it, well, final - meaning unchangeable
Anything not withing a block like a constructor or a method is considered a field.
I am polling the event queue and setting variables in another class depending on the event result.
while(!fin){
pollEvents();
}
And in the event handler:
case Sdl.SDL_MOUSEMOTION:
game.setdx(e.motion.y);
game.setdy(e.motion.x);
break;
I am new to C# from Java. My understanding is that these values will be passed by value rather than reference and am wondering if it would be better to:
make dx and dy in the other class public and simply set the values
use pointers to dx and dy and set the values using them
Figured it out so thought i'd share. Properties are applicable to both classes and structures... I was under the impression they were solely for structures. Anyway, from what I understand, properties are like direct assignments. Syntax:
class ThatWillStoreTheVal{
private bool ford=false;
//seter/getter method called a property
public bool fordP{
set{ford=value;}
get{return ford;}
}
}
class ThatSetsTheProperty{
private ThatWillStoreTheVal ob;
//the assignment. Note that the method like name is called not the variable name
...
if(e.key.keysym.sym==Sdl.SDLK_e) ob.fordP=true;
...