Avoiding Duplication of RiakKey in BaseEntity and derived classes - identifier

I have a base class which is a Riak entity, and some derived classes that extends BaseEntity.
BaseEntity has a field named Identifier which is annotated as #RiakKey.
but apparently this is not enought. It seems that I must have the Identifier field, with the #RuiakKey anotation in each derived class, otherwise I get this exception:
com.basho.riak.client.convert.NoKeySpecifedException
at com.basho.riak.client.bucket.DefaultBucket.fetch(DefaultBucket.java:535)
at com.att.cso.omss.datastore.riak.controllers.RiakBaseController.isEntityExist(RiakBaseController.java:130)
at com.att.cso.omss.datastore.riak.controllers.RiakBaseController.createEntity(RiakBaseController.java:94)
at com.att.cso.omss.datastore.riak.controllers.RiakBaseController.createServiceProvider(RiakBaseController.java:234)
at com.att.cso.omss.datastore.riak.App.serviceProviderTests(App.java:62)
at com.att.cso.omss.datastore.riak.App.main(App.java:38)
So, my current implementation looks like this (duplication of the identifier field):
public class BaseEntity{
#RiakKey
#JsonProperty("Id")
protected String identifier;
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
.
.
.
public class Service extends BaseEntity{
#RiakKey
#JsonProperty("Id")
protected String identifier;
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
is there a way to avoid this duplication?

UPDATED: Thanks to a contribution by someone who saw this question, this is will now be supported as of the 1.0.7 client release. See: https://github.com/basho/riak-java-client/pull/180
Original Answer:
Short answer: No, there's not a way around it currently.
The reason is the com.basho.riak.client.convert.reflect.AnnotationScanner class, how it looks for these annotations, and what we allow the scoping of the fields to be.
It uses Class.getDeclaredFields() which only gets the fields explicitly declared in the class, not inherited ones. The reason for this is that it gets private and protected members, whereas Class.getFields() would get inherited ones but only if they were declared public in a parent class.
One simple way around this would be to recursively scan each parent class up the inheritance tree. Because of how we cache the annotated fields for domain objects this would only be a one time hit and probably wouldn't be too terrible of a thing to do.
If this is something you'd be interested in having added to the client, please feel free to open an issue on github (or code & submit it yourself, of course - we're always thankful for community submissions!).

Related

I want ClassA to get particular a particular instance of ClassB, but can't modify either class directly

Say I have two JdbcTemplates, one for "employee_database" and one for "customer_database". Say a class EmployeeDAO requires the former as a constructor dependency, and CustomerDAO requires the latter. If I were writing these classes myself, I'd do
public class EmployeeDAO {
public EmployeeDAO(#Named("employee") JdbcTemplate employeeJdbcTemplate)
and
bind(JdbcTemplate.class).annotatedWith(Names.named("employee")).toInstance(employeeJdbcTemplateInstance);
And likewise for CustomerDAO
But I can't modify EmployeeDAO to add the Named annotation to the constructor parameters.
What's the canonical way to insure the DAO objects get their respective JdbcTemplates in this scenario without having to instantiate them myself?
In a sense, this is similar to the "robot legs problem", as you're trying to create similar-but-slightly-different trees of objects. In the eponymous problem, you're using a reusable Leg object that receives a #Left Foot and a #Right Foot as needed; in this problem, you're similarly varying the binding of an inner object (JdbcTemplate) based on an outer object's (DAO's) context.
A "cheap way" is to use #Provides methods, which is a particularly low-cost solution if your consumer DAOs have few dependencies and are unlikely to change frequently. Naturally, creating a full Provider would also work too, but this syntax works just fine for most cases.
public class YourModule extends AbstractModule {
#Override public void configure() {}
#Provides EmployeeDao createEmployeeDao( // Name doesn't matter.
#Named("employeeJdbcTemplate") JdbcTemplate employeeTemplate,
Dep2 dep2,
Provider<Dep3> dep3Provider) {
return new EmployeeDao(employeeTemplate, dep2, dep3Provider);
}
}
If the dep list is long, deps change frequently, or multiple classes depend on a JdbcTemplate, then private modules may be the way to go.
install(new PrivateModule() {
#Override public void configure() {
bind(JdbcTemplate.class).toInstance(employeeJdbcTemplate);
expose(EmployeeDao.class);
}
});
The example above uses an anonymous inner class, but you could also create a named class (either top-level or nested) that accepts a JdbcTemplate instance and a DAO class literal, and call it like so:
install(new DaoModule(employeeTemplate, EmployeeDao.class));
install(new DaoModule(customerTemplate, CustomerDao.class));

How do I clean up my Delegate class to be cleaner?

I am writing an SDK and wanted to know how to write things more cleanly.
For example, I have a GodManager delegate class (which will be the central class that a user can interact with) (this is pseudocode-ish):
public class GodManager {
private CloudApi cloudApi;
private SensorApi sensorApi;
private CacheApi cacheApi;
.
. And about 5 more API classes of similar sorts
.
GodManager() {
cloudApi = new CloudApi();
sensorApi = new SensorApi()
cacheApi = new CacheApi();
}
public void someCloudApiMethodAccess() {
cloudApi.someCloudApiMethodAccess();
}
.
.
. And I have about 25 other methods where GodManager delegates to API classes
.
}
How do I allow access for my users via GodManager, but remove these 25 methods that are just proxy methods for each Api class?
I know that Android Wear does something with:
public class Wearable {
public static final com.google.android.gms.wearable.DataApi DataApi;
public static final com.google.android.gms.wearable.MessageApi MessageApi;
public static final com.google.android.gms.wearable.NodeApi NodeApi;
}
Where you can access these APIs in your code:
Wearable.DataApi.getFdForAsset(...)
So I'm guessing that I can mimic this and do something like:
class GodManager {
public static CloudApi CloudApi;
GodManager {
CloudApi = new CloudApi();
}
}
Then in my implementation classes, I can:
class ImplClass {
public void method() {
GodManager.CloudApi.someCloudApiMethodAccess()
}
}
Am I missing anything? Will there be some awkward side-effects that I haven't considered? Any advice would be greatly appreciated in an effort to clean up my GodManager.
Or maybe someone has some other examples that I can look at and learn from?
Creating public fields is usually an antipattern, although there are some legid uses. The danger lies in the fact that if a user has access to your field, it can do ANYTHING with it.
If CloudApi contains public methods or public fields of it's own, that the user should NOT mess with, then te ONLY solution is to make a huge delegate class. If you have full control over CloudApi, and/or you can ensure that it's only public members are those that may be safely, and unconditionally, accessed by others, then you can make the instance public. (which is the legid use)
(Note that making a member private and making a public getter for that method that returns the instance, is exactly the same!)
Even then, you're limiting yourself because you're defining your API (of GodManager) and you're preventing yourself from EVER extending functionality of the referenced instances. For example, you might want to make calls to CloudApi synchronized, or check parameter validity, but don't want (or can) change CloudApi. If you have delegate methods, you can extend the functionality without changing your GodManager API, and existing users don't break.

Why do scope modifiers on fields in domain classes prevent validation?

I'm just starting with Grails (coming from Rails) and I noticed that Grails really doesn't seem to like scope modifiers on fields in domain classes.
I had understood that all unscoped fields in a domain class were by default public, but if you actually declare it public, Grails won't validate it.
class Person {
public String firstName
public String middleName
public String lastName
}
If you add a constraint, Grails will throw a NotReadablePropertyException exception when you call validate()
class Person {
public String firstName
public String middleName
public String lastName
static constraints = {
middleName nullable: true
}
}
However if you take out the public declaration, everything works normally.
Can someone explain what's going on behind the scenes with the scoping in domain classes? Hard to understand why explicitly declaring something public which is already public would break the framework. I'm guessing you wouldn't want to declare anything 'private' either, although it would be nice if there was away that a fields which shouldn't be manipulated directly could be hidden from consumers of the domain class.
When you add a field to a Groovy class without a scope modifier, it's more that it's inferred to be public than being actually public. The compiler converts the field to a private field and generates a public getter and a setter for it, although it won't overwrite a getter or setter that you wrote. This is convenient because you can later write getters and/or setters to implement business logic and not affect the callers.
But a public field (declared as 'public') is just that - a public field. There's no generated getter or setter. I recommend using a decompiler to see this in action - create a simple POGO in src/groovy, e.g.
class Thing {
String realProperty
public String fieldButNotProperty
}
and open up the .class file with http://jd.benow.ca/ or another decompiler.
GORM automatically assumes that typed properties are persistent unless you exclude some with the transients list. The type is required so it knows how to persist the data, and properties like def name will be ignored. Properties in this sense are similar to JavaBean properties - a matched getter/setter pair.
Hibernate has no support for Groovy and doesn't know what's going on under the hood - it just calls your getters and setters to set and access field data during persistence. So the Groovy compiler adding those in makes it easy for POGOs in Grails to be persisted by Hibernate. And you could do this yourself - add in a getter and setter with correct names and data type (e.g. String getName() and void setName(String name) and it will be treated as a persistent property, even if you do nothing with the values.
The reason for the NotReadablePropertyException is that there's no getter to call for your 'property'. Even though your fields are perfectly accessible, you've effectively hidden them from GORM and Hibernate.
If you add a constraint, Grails will throw a NotReadablePropertyException exception when you call validate()
Never noticed this before, sounds like a bug
it would be nice if there was away that a fields which shouldn't be manipulated directly could be hidden from consumers of the domain class.
If you want to prevent direct access to a property, simply add a getter and setter. In the (contrived) example below, I ensure that name is always read/written as an upper case string.
class Person {
public String firstName
public String middleName
public String lastName
public void setFirstName(String name) {
this.firstName = name.toUpperCase()
}
public String getFirstName() {
return this.firstName.toUpperCase()
}
}

Action property of interface type

With my understading, the nature of a Action is that properties can be pushed w/ request parameter values. And, one wonderful feature is that Struts2 allows you to directly populate parameter values against Class type property ;)
Assuming there exists a Action and property class as below,
class Action extends ActionSupport {
User user;
#Action(value="hello" {#result=(.......)})
public void execute() {
........
}
.....
public void setUser(User user) {
this.user = user;
}
public User getUser() {
return this.user;
}
}
class User {
String name;
.....
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
you could populate User class property by doing like this.
http://...../hello.action?user.name=John or via jsp page
Then, I realize that there are actually people make an Action property as a Interface type. My question is what is the reason behind this. If there is a sample code demonstrating it will be great.
Thanks in advance!
Sorry, but your question does not make much sense.
To clarify:
"Properties": in Java a "property" of a class is something that is accesible via getter/setters method (setXXX() / getXXX() => property XXX), tipically (but not necessarily) corresponds to a private field.
In Struts2 you have an Action object and typically (not necessarily, not always) the properties are populated (set) from the request (via the "Parameters" interceptor), and later in the view stage read from the JSP (or whatever) page.
So, in your example, for the request http://...../hello.action?user.name=John , Struts2 would try to find in your action (...actually in your value stack) a property "user" which has a property "name", and try to set it (if the types are convertible). That is, he would try to call something like yourAction.getUser().setName("John") . Struts2 does not know -does not care- what type are the properties "User" or "Name", even if they are real fields or not. (They are expected to behaviour as "beans", though: i.e. they should have a default constructor).
Why and when you should code interfaces instead of concrete classes is something that is explained in any Java book, it's just a standard good practice and there are tons of pages about it. It has nothing to do with Struts2. In this context, for an Action, one is tipically only interested in doing so for some "service" fields, objects that are typically long-lived (perhaps singletons), are not instantiated by the action itself (nor by the request!). So, those interfaces are NOT the properties we are considering here, they ( usually ) are not exposed publically and usually are not populated nor read from the client.

How can I exclude some public properties from being serialized into a JsonResult?

I have a custom viewmodel which serialized using a JsonResult. The ViewModel has some properties which have to be public, but at the same time these properties should not be visible in the resulting Json output.
I've already tried using the [NonSerialized] attribute, but that did not seem to have any effect.
Is there any simple way to do this? Or would I have to code my own result type (in which case I probably won't bother)?
You can put a [ScriptIgnore] attribute on the members that shouldn't be serialized. See ScriptIgnoreAttribute Class in MSDN for an example.
Just create an interface to return instead of a class.
public interface IMyViewModel {
string MyPublicProperty { get; set; }
}
Then create a class that inherits the interface
public class MyViewModel : IMyViewModel {
public string MyPublicProperty { get; set; }
public string MyNotSoPublicProperty { get; set; }
}
And return the interface, not the class, in the Controller Action
public JsonResult MyJson(){
IMyViewModel model = new MyViewModel();
return Json(model);
}
And the resulting JSON will be
{
'MyPublicProperty': ''
}
One of the challenges in client-side scripting is, that if you're changing your classes, you have no idea whether you're destroying the client-side implementation or not. If you use interface types in your JSON, you understand that if you change the interface, you're doing something that potentially may be killing the client side implementation. And it also saves you from double-checking the client side in vain if you're changing something that is NOT in the inteface (thus not being serialized).
Also, many times, your ViewModels might have large collections or complex types in them that you don't necessarily want to output to the client. These might take a long time to serialize or expose information that simply does not belong into the client code. Using interfaces will make it more transparent to know what is being in the output.
Also, using attributes such as [ScriptIgnore] on a property only applies to a specific scenario (JavaScript Serialization) forcing you to face the exact same problem if you're later serializing to XML for example. This would unnecessarily litter your viewmodels with tons of attributes. How many of them you really want in there? Using intefaces applies anywhere and no viewmodel needs to be littered with extra attributes.
Have a look at JSON.NET from James Newton-King. It'll do what you're looking for.
Extend the JavaScriptConverter class to not include properties with the NonSerializedAttribute. Then you can create a custom ActionResult that uses your JavaScriptConverter to serialize the object.
This creates a solid and testable class without having to (re)generate wrapper classes or using anonymous objects.
You can create a wrapper class that exposes only those properties that you want in the JsonResult. In the example below, Cow has 2 properties - "Leg" and "Moo". Suppose you want to only expose "Leg" as a property. Then
Dim cw as CowWrapper = New CowWrapper(c)
will return a wrapper class that only exposes "Leg". This is also useful for things like DataGridView if you only want to display some subset of the properties.
Public Class Cow
Public ReadOnly Property Leg() as String
get
return "leg"
end get
end Property
Public ReadOnly Property Moo() as String
get
return "moo"
end get
end Property
end class
Public Class CowWrapper
Private m_cow as Cow = Nothing
Public Sub New(ByVal cow as Cow)
m_cow = cow
end Sub
m_cow = cow
Public ReadOnly Property Leg() as String
get
return m_cow.Leg()
end get
end Property
end Class
Not exactly the answer you're looking for, but you can cheat Json() using the following code and anonymous classes:
MyModel model = ...;
return Json(new MyModel {model.Prop1, model.Prop2});
I needed the answer to this for ASP.NET Core 6.x and couldn't find it.
I finally found the answer and it is :
[System.Text.Json.Serialization.JsonIgnore]
Here's an example in a class
class Sample{
// Item will not be serialized
[System.Text.Json.Serialization.JsonIgnore]
String Item{get;set;}
// Count will be serialized
int Count{get;set;}
}

Resources