Getter is not associated to any field - Realm - java

I am new to using Realm library and was trying to implement it in my android application. Just got stuck at a point where I am trying to section my listview based on the view type of a particular element in my json response.
I have tried to implement the sections with recycler view but the problem is I have 2 view types and addition of headers for those view types was causing an issue. Since Realm doesn't have the support of RecyclerAdapter, I created an implementation that will use a custom adapter that supports the RecyclerView.
So, I though I will use a ListView and try to use a simple interface for each of the Object type to determine the type and then insert the Headers based on the position of the group.
For some reason Realm is not allowing me to implement an interface in a class which extends RealmObject.
This is how that class looks like :
import com.google.gson.annotations.SerializedName;
import io.realm.RealmObject;
import io.realm.annotations.Ignore;
import io.realm.annotations.PrimaryKey;
public class TestClass extends RealmObject implements Subjects {
#PrimaryKey
#SerializedName("subjectID")
private String subjectID;
private String subjectDate;
#SerializedName("subjectDescription")
private String subjectDescription;
public String getSubjectID() {
return subjectID;
}
public void setSubjectID(String subjectID) {
this.subjectID = subjectID;
}
public String getSubjectDate() {
return subjectDate;
}
public void setSubjectDate(String subjectDate) {
this.subjectDate = subjectDate;
}
public String getSubjectDescription() {
return subjectDescription;
}
public void setSubjectDescription(String subjectDescription) {
this.subjectDescription = subjectDescription;
}
#Override
public boolean isSubjectA() {
return true;
}
#Override
public boolean isFoo() {
return false;
}
#Override
public boolean isBar() {
return false;
}
}
And this is the Compilation Error log :
Error:(76, 20) error: Getter isSubject is not associated to any field.
Note: Creating DefaultRealmModule
Warning:File for type 'io.realm.DefaultRealmModule' created in the last round will not be subject to annotation processing.
Warning:File for type 'io.realm.DefaultRealmModuleMediator' created in the last round will not be subject to annotation processing.
2 warnings
I have no idea why is complaining about this issue but its not compiling the project.
I read a few discussion about the issue here : link .. Apparently, there's an open discussion about this issue but any other help will be really appreciated.. Thank you

You have an typo in your field's name, also it shouldn't have prefix, so it would be "subject", and getter must be isSubject()
#Ignore
private boolean subject = false;
public boolean isSubject() {
return subject;
}
.

Related

Modeling circular dependencies while maintaining data integrity

I'm designing a music information system. I have a couple of entities that are connected to each other.
Below is part of the domain code.
class Album {
private Set<Track> tracks;
private boolean published;
public Set<Track> getTracks() {
return this.tracks;
}
public boolean isPublished() {
return this.published;
}
public void publish() {
System.out.println("Album.publish() called");
this.published = true;
this.tracks.forEach(track -> track.publish());
}
}
class Track {
private boolean published;
private Album album;
public boolean isPublished() {
return this.published;
}
public Album getAlbum() {
return this.album;
}
public void publish() {
// if track is single (this.album == null), set published to true
// if track is part of an album and the album is NOT published, return;
// if track is part of an album and the album is published, set published to true
if(this.album != null && !this.album.isPublished())
return;
this.published = true;
}
}
Track is an independent entity. It can be a single track (I.e. without an Album). So the album attribute is actually needed.
One domain rule is that when an album is archived (i.e. not published), its tracks cannot be published neither and if an album is published, any of its tracks can either be published or archived.
The problem is that when an album is published (e.g. album1.publish()), its tracks' publish() method is called as well. But track1.publish() checks if the album is published based on the copy it already has (which is not published).
How can I solve the problem?
If you split domain model entities by behaviour, you can get rid of described limitations
Let's have some interfaces for such entities:
interface AlbumId{
String asString();
AlbumId Absent = () -> "NO ALBUM AT ALL";
}
interface Publication{
void publish() throws Exception;
void archive() throws Exception;
boolean published();
}
interface Track{
TrackId id();
AlbumId albumId(); //smart type (as DDD suggest), therefore, no more nulls
}
Now you may enforce rules by creating class that will get you a list of tracks you can publish:
public class TracksReadyToPublishOf implements Supplier<Map<TrackId, TrackPublication>>{
//this class may access to cache and have dosens of other optimizations
public TracksReadyToPublishOf(AlbumId id){...}
#Override public get(){...}
}
Then you can reuse your code to check your rules anywhere:
public class TrackPublication implements Publication {
private final Track track;
private final Supplier<Map<TrackId, TrackPublication>> allowedTracks;
//easy for unit testing
public SmartTrackPublication(Track track, Supplier<Map<TrackId, TrackPublication>> allowedTracks){
this.track = track;
this.allowedTracks = allowedTracks;
}
public SmartTrackPublication(Track track){
this(track, new TracksReadyToPublishOf(track.albumId());
}
#Override
public publish() throws AlbumArchivedException{
if(this.albumId != AlbumId.Absent){
if(!this.allowedTracks.get().containsKey(this.track.id())){
throw new AlbumArchivedException();
}
}
this.allowedTracks.get().get(this.id()).publish();
}
}
And for album publishing:
public class AlbumPublication implements Publication{
private final AlbumId id;
private final Producer<Map<TrackId, TrackPublication>> tracks
private AlbumWithTracks(AlbumId id, Producer<Map<TrackId, TrackPublication>> tracks){
this.id = id;
this.tracks = tracks;
}
public AlbumWithTracks(AlbumId id){
this(id, new TracksReadyToPublishOf(id))
}
...
#Override publish() throws Exception{
//code for publishing album
for(TrackPublication t : Arrays.asList(
this.tracks.get()
)){
t.publish(); //track can publish anyway if it presents in list above
}
}
}

Objectify load groups not filtering Ref<> data

I am using Google Cloud Endpoints with Objectify to create a Java backend to my mobile application. Everything works great except that the full JSON tree is being returned even when I use Objectify load groups. For example, a subset of the tree includes a Building class that has an Address and a list of Floors:
public class Building {
#Load(Everything.class)
private Ref<Address> address;
#Load(Lite.class})
private List<Ref<Floor>> floors = new ArrayList<Ref<Floor>>();
public Address getAddress() {
return Deref.deref(address);
}
public List<Floor> getFloors() {
return Deref.deref(floors);
}
}
public class BuildingEndpoint {
#ApiMethod(name = "building.getLite", path = "building_get_lite")
public Building getLite(#Named("id") Long id) {
Building building = ofy().load().group(Lite.class).type(Building.class).id(id).now();
return building;
}
}
According to the Objectify docs, the Address should be loading but NOT the Floors, however, everything is being loaded (as well as children classes of the Floor, all the way down in the object hierarchy).
Just in case the Deref is the issue, I'm including it here:
public class Deref {
public static class Func<T> implements Function<Ref<T>, T> {
public static Func<Object> INSTANCE = new Func<Object>();
#Override
public T apply(Ref<T> ref) {
return deref(ref);
}
}
public static <T> T deref(Ref<T> ref) {
return ref == null ? null : ref.get();
}
#SuppressWarnings({ "unchecked", "rawtypes" })
public static <T> List<T> deref(List<Ref<T>> reflist) {
return Lists.transform(reflist, (Func)Func.INSTANCE);
}
}
Any insights as to why load groups is not working and the FULL object hierarchy is still being loaded is much appreciated.

It is possible to check if import is wrong? while writing a custom rule

I would like to write a java rule Will generate a issue if an imported class is an APIClass annotation and the imported class has issues. I am following this tutorial.
The code:
First, I wrote a simple rule:
#Rule( key = "ForbidClassVariables", name = "ForbidClassVariables")
public class ForbidClassVariables extends BaseTreeVisitor implements JavaFileScanner {
private JavaFileScannerContext context;
#Override
public void scanFile(JavaFileScannerContext context) {
this.context = context;
if (context.getSemanticModel() != null) {
scan(context.getTree());
}
}
#Override
public void visitClass(ClassTree tree) {
if (tree.modifiers().annotations().size() > 0 && hasAnnotation(tree.modifiers().annotations(), "APIClass")) {
if (hasClassVariables(tree)) {
this.context.reportIssue(this, tree.simpleName(), "Do not use class variables on API Classes.");
}
}
super.visitClass(tree);
}
private boolean hasAnnotation(List<AnnotationTree> annotations, String annotationName) {
for (AnnotationTree annotation : annotations) {
if (annotation.annotationType().is(Tree.Kind.IDENTIFIER)
&& ((IdentifierTree) annotation.annotationType()).name().equals(annotationName)) {
return true;
}
}
return false;
}
private boolean hasClassVariables(ClassTree tree) {
for (Tree member : tree.members()) {
if (member.is(Tree.Kind.VARIABLE)) {
VariableTree variableTree = (VariableTree) member;
Symbol symbol = variableTree.symbol();
if (!symbol.isStatic() || !symbol.isFinal()) {
return true;
}
}
}
return false;
}
}
I created a test class file ExampleA.java
package br.com.test;
#APIClass
public class ExampleA {
private String name;
}
When I run the test, generates an error on line 4, It was as expected.
The point of the problem: I created another rule:
#Rule( key = "CheckIFClassIsOK", name = "CheckIFClassIsOK")
public class CheckIFImportedClassIsOK extends BaseTreeVisitor implements JavaFileScanner{
private JavaFileScannerContext context;
#Override
public void scanFile(JavaFileScannerContext context) {
this.context = context;
if (context.getSemanticModel() != null) {
scan(context.getTree());
}
}
#Override
public void visitImport(ImportTree tree) {
IdentifierTree identifier = ((MemberSelectExpressionTree) tree.qualifiedIdentifier()).identifier();
System.out.println(identifier); // Shows ExampleA
// At this point I need re-scan ExampleA class and IF the scan generate any issue
// Will generate another here Issue on ExampleB
super.visitImport(tree);
}
}
And used this file to test:
import br.com.test.ExampleA;
public class ExampleB {
private ExampleA exampleA;
}
The problem is, when I am visiting an import, if the imported class has an APIClass annotation and has issues, it will generate an issue on ExampleB.java to avoid using this import because has an issue. I have searched a lot on the Tree classes, but I didn't find anything useful. I think I need to force the re-scan on ExampleA.java, but how? Anyone have ideas?
Sonar version: 6.2
Java plugin version: 4.5.0.8398
Thanks for attention
Unfortunately, this is not possible. There is no way in the API to request parsed tree from another file. However you are able to retrieve semantic information about members in class ExampleB, but this doesn't include annotations.

For a large validation task is chain of responsibility pattern a good bet?

I need to build a process which will validate a record against ~200 validation rules. A record can be one of ~10 types. There is some segmentation from validation rules to record types but there exists a lot of overlap which prevents me from cleanly binning the validation rules.
During my design I'm considering a chain of responsibility pattern for all of the validation rules. Is this a good idea or is there a better design pattern?
Validation is frequently a Composite pattern. When you break it down, you want to seperate the what you want to from the how you want to do it, you get:
If foo is valid
then do something.
Here we have the abstraction is valid -- Caveat: This code was lifted from currrent, similar examples so you may find missing symbology and such. But this is so you get the picture. In addition, the
Result
Object contains messaging about the failure as well as a simple status (true/false).
This allow you the option of just asking "did it pass?" vs. "If it failed, tell me why"
QuickCollection
and
QuickMap
Are convenience classes for taking any class and quickly turning them into those respected types by merely assigning to a delegate. For this example it means your composite validator is already a collection and can be iterated, for example.
You had a secondary problem in your question: "cleanly binding" as in, "Type A" -> rules{a,b,c}" and "Type B" -> rules{c,e,z}"
This is easily managed with a Map. Not entirely a Command pattern but close
Map<Type,Validator> typeValidators = new HashMap<>();
Setup the validator for each type then create a mapping between types. This is really best done as bean config if you're using Java but Definitely use dependency injection
public interface Validator<T>{
public Result validate(T value);
public static interface Result {
public static final Result OK = new Result() {
#Override
public String getMessage() {
return "OK";
}
#Override
public String toString() {
return "OK";
}
#Override
public boolean isOk() {
return true;
}
};
public boolean isOk();
public String getMessage();
}
}
Now some simple implementations to show the point:
public class MinLengthValidator implements Validator<String> {
private final SimpleResult FAILED;
private Integer minLength;
public MinLengthValidator() {
this(8);
}
public MinLengthValidator(Integer minLength) {
this.minLength = minLength;
FAILED = new SimpleResult("Password must be at least "+minLength+" characters",false);
}
#Override
public Result validate(String newPassword) {
return newPassword.length() >= minLength ? Result.OK : FAILED;
}
#Override
public String toString() {
return this.getClass().getSimpleName();
}
}
Here is another we will combine with
public class NotCurrentValidator implements Validator<String> {
#Autowired
#Qualifier("userPasswordEncoder")
private PasswordEncoder encoder;
private static final SimpleResult FAILED = new SimpleResult("Password cannot be your current password",false);
#Override
public Result validate(String newPassword) {
boolean passed = !encoder.matches(newPassword,user.getPassword());
return (passed ? Result.OK : FAILED);
}
#Override
public String toString() {
return this.getClass().getSimpleName();
}
}
Now here is a composite:
public class CompositePasswordRule extends QuickCollection<Validator> implements Validator<String> {
public CompositeValidator(Collection<Validator> rules) {
super.delegate = rules;
}
public CompositeValidator(Validator<?>... rules) {
super.delegate = Arrays.asList(rules);
}
#Override
public CompositeResult validate(String newPassword) {
CompositeResult result = new CompositeResult(super.delegate.size());
for(Validator rule : super.delegate){
Result temp = rule.validate(newPassword);
if(!temp.isOk())
result.put(rule,temp);
}
return result;
}
public static class CompositeResult extends QuickMap<Validator,Result> implements Result {
private Integer appliedCount;
private CompositeResult(Integer appliedCount) {
super.delegate = VdcCollections.delimitedMap(new HashMap<PasswordRule, Result>(), "-->",", ");
this.appliedCount = appliedCount;
}
#Override
public String getMessage() {
return super.delegate.toString();
}
#Override
public String toString() {
return super.delegate.toString();
}
#Override
public boolean isOk() {
boolean isOk = true;
for (Result r : delegate.values()) {
isOk = r.isOk();
if(!isOk)
break;
}
return isOk;
}
public Integer failCount() {
return this.size();
}
public Integer passCount() {
return appliedCount - this.size();
}
}
}
and now a snippet of use:
private Validator<String> pwRule = new CompositeValidator<String>(new MinLengthValidator(),new NotCurrentValidator());
Validator.Result result = pwRule.validate(newPassword);
if(!result.isOk())
throw new PasswordConstraintException("%s", result.getMessage());
user.obsoleteCurrentPassword();
user.setPassword(passwordEncoder.encode(newPassword));
user.setPwExpDate(DateTime.now().plusDays(passwordDaysToLive).toDate());
userDao.updateUser(user);
Chain of responsibility implies that there is an order in which the validations must take place. I would probably use something similar to the Strategy pattern where you have a Set of validation strategies that are applied to a specific type of record. You could then use a factory to examine the record and apply the correct set of validations.

RequestFactoryEditorDriver doesn't save full graph even though "with()" is called. Is circular reference an issue?

Could you guys please help me find where I made a mistake ?
I switched from SimpleBeanEditorDriver to RequestFactoryEditorDriver and my code no longer saves full graph even though with() method is called. But it correctly loads full graph in the constructor.
Could it be caused by circular reference between OrganizationProxy and PersonProxy ? I don't know what else to think :( It worked with SimpleBeanEditorDriver though.
Below is my client code. Let me know if you want me to add sources of proxies to this question (or you can see them here).
public class NewOrderView extends Composite
{
interface Binder extends UiBinder<Widget, NewOrderView> {}
private static Binder uiBinder = GWT.create(Binder.class);
interface Driver extends RequestFactoryEditorDriver<OrganizationProxy, OrganizationEditor> {}
Driver driver = GWT.create(Driver.class);
#UiField
Button save;
#UiField
OrganizationEditor orgEditor;
AdminRequestFactory requestFactory;
AdminRequestFactory.OrderRequestContext requestContext;
OrganizationProxy organization;
public NewOrderView()
{
initWidget(uiBinder.createAndBindUi(this));
requestFactory = createFactory();
requestContext = requestFactory.contextOrder();
driver.initialize(requestFactory, orgEditor);
String[] paths = driver.getPaths();
createFactory().contextOrder().findOrganizationById(1).with(paths).fire(new Receiver<OrganizationProxy>()
{
#Override
public void onSuccess(OrganizationProxy response)
{
if (response == null)
{
organization = requestContext.create(OrganizationProxy.class);
organization.setContactPerson(requestContext.create(PersonProxy.class));
} else
organization = requestContext.edit(response);
driver.edit(organization, requestContext);
}
#Override
public void onFailure(ServerFailure error)
{
createConfirmationDialogBox(error.getMessage()).center();
}
});
}
private static AdminRequestFactory createFactory()
{
AdminRequestFactory factory = GWT.create(AdminRequestFactory.class);
factory.initialize(new SimpleEventBus());
return factory;
}
#UiHandler("save")
void buttonClick(ClickEvent e)
{
e.stopPropagation();
save.setEnabled(false);
try
{
AdminRequestFactory.OrderRequestContext ctx = (AdminRequestFactory.OrderRequestContext) driver.flush();
if (!driver.hasErrors())
{
// Link to each other
PersonProxy contactPerson = organization.getContactPerson();
contactPerson.setOrganization(organization);
String[] paths = driver.getPaths();
ctx.saveOrganization(organization).with(paths).fire(new Receiver<Void>()
{
#Override
public void onSuccess(Void arg0)
{
createConfirmationDialogBox("Saved!").center();
}
#Override
public void onFailure(ServerFailure error)
{
createConfirmationDialogBox(error.getMessage()).center();
}
});
}
} finally
{
save.setEnabled(true);
}
}
}
with() is only used for retrieval of information, so your with() use with a void return type is useless (but harmless).
Whether a full graph is persisted is entirely up to your server-side code, which is intimately bound to your persistence API (JPA, JDO, etc.)
First, check that the Organization object you receive in your save() method on the server-side is correctly populated. If it's not the case, check your Locators (and/or static findXxx methods) ; otherwise, check your save() method's code.
Judging from the code above, I can't see a reason why it wouldn't work.
It took me some time to realize that the problem was the composite id of Person entity.
Below is the code snippet of PojoLocator that is used by my proxy entities.
public class PojoLocator extends Locator<DatastoreObject, Long>
{
#Override
public DatastoreObject find(Class<? extends DatastoreObject> clazz, Long id)
{
}
#Override
public Long getId(DatastoreObject domainObject)
{
}
}
In order to fetch child entity from DataStore you need to have id of a parent class. In order to achieve that I switched "ID class" for Locator<> to String which represents textual form of Objectify's Key<> class.
Here is how to looks now:
public class PojoLocator extends Locator<DatastoreObject, String>
{
#Override
public DatastoreObject find(Class<? extends DatastoreObject> clazz, String id)
{
Key<DatastoreObject> key = Key.create(id);
return ofy.load(key);
}
#Override
public String getId(DatastoreObject domainObject)
{
if (domainObject.getId() != null)
{
Key<DatastoreObject> key = ofy.fact().getKey(domainObject);
return key.getString();
} else
return null;
}
}
Please note that your implementation may slightly differ because I'm using Objectify4.

Categories

Resources