How to use entity class which extends another class in a Room? - java

I tried searching everything but i didn't find any solution. One question is similar but no one has answered it properly. Moving to the question, I have a class which has room entity annotation and the same class extends another class (which is Library class). Now when i run the project I get an errors like Error:Cannot find getter for field. Library's super class making issue here as it works when i remove it. Please tell me how can i make room work with subclass as entity extending super class. Thank you for your time.
#Entity(tableName = "event")
public class EventDetails extends ParentEntity implements Parcelable{
#PrimaryKey(autoGenerate = true)
int id;
String name;
Calendar startDay = Calendar.getInstance();
Calendar endDay = Calendar.getInstance();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Calendar getStartDay() {
return startDay;
}
public void setStartDay(Calendar startDay) {
this.startDay = startDay;
}
public Calendar getEndDay() {
return endDay;
}
public void setEndDay(Calendar endDay) {
this.endDay = endDay;
}
public void setName(String name) {
this.name = name;
}
#Override
public String getName() {
return name;
}
}
public class ParentEntity {
private Calendar mDay;
public Calendar getmDay() {
return mDay;
}
public void setmDay(Calendar mDay) {
this.mDay = mDay;
}
}

This seems to be mainly a naming problem: after changing the field name from mDay to just day and renaming the setter/ getter accordingly, everything compiles.
It looks like the method names which Android Studio generates from mDay are not the ones which Room is looking for.
Since you are in a position to use different field names in the parent class, this looks like the best solution.
If it is not possible to change the library, it is especially not possible to mark fields in the library class with Ignore, so one can't fix the problem by inserting an intermediate class into the inheritance hierarchy. (I tried using a Constructor for EventDetails with the private field as argument but this too did not work)
So in this case I think your best option would be not to try to extend from the library class (but maybe from some "surrogate parent" class) and to bridge the gap to the library class with the help of some factory class.

Related

Finding non-referenced class attributes in Eclipse

I wonder if there are another ways to find attributes in specific class are non-referenced by other classes (I mean, non used attributes).
My way is like that, for example I have a class like:
public class EABHeaderInformation implements Serializable{
/**
*
*/
private static final long serialVersionUID = -4986763088497593972L;
//BargainFinder - AlternateBooking
private int multiTicketSequencdNmbr;
private String resBookDesigCode;
private LocalDateTime departureDate;
private LocalDateTime lastTicketingDate;
private List<String> text;
private String validatingCarrierCode;
public String getValidatingCarrierCode() {
return validatingCarrierCode;
}
public void setValidatingCarrierCode(String validatingCarrierCode) {
this.validatingCarrierCode = validatingCarrierCode;
}
public int getMultiTicketSequencdNmbr() {
return multiTicketSequencdNmbr;
}
public void setMultiTicketSequencdNmbr(int multiTicketSequencdNmbr) {
this.multiTicketSequencdNmbr = multiTicketSequencdNmbr;
}
public String getResBookDesigCode() {
return resBookDesigCode;
}
public void setResBookDesigCode(String resBookDesigCode) {
this.resBookDesigCode = resBookDesigCode;
}
public LocalDateTime getDepartureDate() {
return departureDate;
}
public void setDepartureDate(LocalDateTime departureDate) {
this.departureDate = departureDate;
}
public LocalDateTime getLastTicketingDate() {
return lastTicketingDate;
}
public void setLastTicketingDate(LocalDateTime lastTicketingDate) {
this.lastTicketingDate = lastTicketingDate;
}
public List<String> getText() {
return text;
}
public void setText(List<String> text) {
this.text = text;
}}
It's a simple POJO with getter and setters. I check every getter and setter with 'Open Call Hierarchy' in Eclipse, to find out if the attribute is used by others or not. But it takes a lot of time when I work on bigger classes than this.
So, is there a faster way to do this? Thanks for replies.
Eclipse can already create a warning or error for unused private members, but for public ones the Eclipse stance has always been that it's not a valuable feature. I tend to disagree, because many users have a limited scope that would be useful (specifically, all, or a subset of, the projects in the workspace). See this feature request, this one, and this one.
There are some third party options, such as UCDetector and this simple plug-in example.
See also this SO question and the answers.

Custom code generation for JPA entities from database

I'm here asking for a simple way to add some custom code in the JPA Entity generated by Eclipse from database.
Basically what I want to achieve is to add public String properties containing the names of the entity properties, and use them when I need to provide "property name" as String and be sure that there won't be runtime access errors.
Something like this
#Entity
#Table(name="clients")
#NamedQuery(name="ClientModel.findAll", query="SELECT c FROM ClientModel c")
public class ClientModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="id_client")
private long idClient;
public String name;
public ClienteModel() {
}
public long getIdClient() {
return this.idClient;
}
public void setIdClient(long idClient) {
this.idClient = idClient;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
//CUSTOM CODE
public static final String idClientProperty = "idClient";
public static final String nameProperty = "name";
}
So i could use property name like
ClientModel.nameProperty
and be compile-time safe of his existence and in case of names refactoring after a further entity generation.
I'm aware of the existence of Telosys Tools & co., but I hoped there could be something simplier/faster (like a custom class provided as plugin in WSDL_to_entity generation with JAXB)
Thank you.
In the end I've used Telosys Tools, even if I didn't want to add another tool to my project,
Is kinda easy to set up, just read here
https://sites.google.com/site/telosystools/getting-started/21-configure-a-project
In my specific case i've added to the template "JPA_bean_with_links" this code during getters creation
#if ( $field.getter ) public static String ${field.getter}Property() {
return "$field.name";
}
#end

How to implement usage dependency, Enumeration data type in Java? Confusion to implement Aggregation, Composition

I have to implement the following class diagram to the java code. This diagram is very complicated and some parts creates confusion. This question definitely going to help me a lot as well as any reader because it contains several important aspects of UML diagram.
class Book{
String isbn;
String publisher;
String publishDate;
int pages;
}
class BookItem extends Book{
String barcode;
boolean isReferenceOnly;
}
class Author{
String name;
String biography;
Collection<Book> book;
}
class Account{
String number;
List<History> history;
String openDate;
AccountState state;
public Account(AccountState state){
this.state = state;
}
}
enum AccountState{
Active,
Frozen,
Closed
}
class Catalog implements Search, Manage{
List<BookItem> bookItem;
/* Implement the methods of Manage interface */
void add(BookItem item){ }
void remove(BookItem item){ }
/* Implement the methods of Search interface */
int search(BookItem item){ }
}
class Account{
String number;
List<History> history;
Student student = new Student();
void setStudent(Student student){
this.student = student;
}
}
interface Search{
int search(BookItem item);
}
interface Manage{
void add(BookItem item);
void remove(BookItem item);
}
class Student{
String name;
String address;
Search searchBook = new Catalog();
}
class Librarian{
String name;
String address;
String position;
Search searchBook = new Catalog();
Manage manage = new Catalog();
Account account = new Account();
void setAccount(Account account){
this.account = account;
}
class Library{
String name;
String Address;
List<BookItem> bookItem = new ArrayList<BookItem>();
Catalog catalog = new catalog();
List<Account> accounts = new ArrayList<Account>();
Library(Catalog catalog){
this.catalog = catalog;
}
void setBookItem(List<BookItem> bookItem){
this.bookItem = bookItem;
}
void setAccounts(List<Account> accounts){
this.accounts = accounts;
}
}
I implemented in the following way but confusion arise in various cases:
How to implement Class Student use the interface Search.
How to implement Class Librarian use the interfaces Search and Manage.
Why we are not use association instead of usage dependency.
How to implement that Enumeration data type in this case with usage dependency [I have just considered AccountState as a class, i the it is a wrong implementation].
How to use AccountState in the Account [I have just created a object of AccountState].
After read many blogs still unable to implement Aggregation and Composition confidently. Note: In this diagram 3 Aggregations and 1 Composition Exist. Those are:
(a) Library consists of many Account. {Aggregation}
(b) Many Book Item is the part of Library. {Aggregation}
(c) An Account is the part of a Student. {Aggregation}
(d) Library must have a Catalog. {Composition}
Please give your valuable advice so i can learn it well. Thanking you.
Since this question is homework for learning purposes, I will post only examples of how to implement the things you need to review and won't give a direct answer about how to apply them to your current design.
Enumeration in Java is implemented by using enum.
enum WeekDays {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY;
}
Aggregation/Composition means to have a field of the other class. If it's a weak association (aggregation), it should be initialized by the setter or another method. If it's a strong association, it should be initialized in the class constructor since it is needed for the class to live/work.
class WeakAssociation { }
class StrongAssociation { }
class NeedWeekAndStrongAssociation {
private WeakAssociation weakAssociation;
private StrongAssociation strongAssociation;
public NeedWeekAndStrongAssociation(StrongAssociation strongAssociation) {
this.strongAssociation = strongAssociation;
}
public void setWeakAssociation(WeakAssociation weakAssociation) {
this.weakAssociation = weakAssociation;
}
}
Usage dependency means that the class/interface will use the other class/interface within one or more of its methods:
class WantToBeUsed {
public void methodToBeUsed(String data) {
//fancy implementation
}
}
class CannotDoThisAlone {
public void cannotDoItAlone(String data) {
WantToBeUsed wantToBeUsed = new WantToBeUsed();
wantToBeUsed.methodToBeUsed(data);
}
}

Display only 1 field in Nested Object Metawidget

Using the metawidget to build some flexible UI in Java: https://sourceforge.net/projects/metawidget/
public class Cohort {
private int id;
private Project project;
private Member teamLead;
public Cohort() { }
#UiHidden
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public Project getProject() { return project; }
public void setProject(Project project) { this.project = project; }
public Member getTeamLead() { return teamLead; }
public void setTeamLead(Member teamLead) { this.teamLead = teamLead; }
}
Cohort is the class inspected. However as is desirable it recursively inspects both the Project and Member classes.
When displayed on the UI, it will display all the fields for each of the classes. However I would only like to display the "Name" field of the Project and firstName + last Name of the Member.
There are a number of ways to achieve this. I'll start with one and let me know if it's sufficient for your needs:
a) mark the fields of Project/Member that you don't want to see as UiHidden (you don't say what those fields are, but you seem to have gotten the idea because you are already hiding 'Cohort.getId'). Note you can also reuse existing annotations (like JPA annotations) for this purpose.
b) mark 'Cohort.getProject' and 'Cohort.getTeamLead' as UiLabel( "" ). This will suppress the sub-label for the sub-object, and make its fields appear as if part of the original object.

In JAXB, how to use #XmlJavaTypeAdapters annotation?

I want to change "javax.xml.datatype.XMLGregorianCalendar" to "java.util.Date" when unmarshalling from xml to Java class of JAXB.
But I don't put any annotations of #XmlJavaTypeAdapter in Java classes.
So, I'm going to try to use an annotation of #XmlJavaTypeAdapters, but I don't know how to use it...
Please show me examples for using it.
As an interesting aside, you don't actually need to adapt XMLGregorianCalendar to Date, since JAXB supports java.util.Date natively -- like this:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement
public class Example {
#XmlSchemaType(name = "date")
public Date publishingDate;
}
If you need it, #XmlJavaTypeAdapter can work like this, assuming your custom class:
public class SillyDate {
public SillyDate(int year, int month, int day) {
super();
this.year = year;
this.month = month;
this.day = day;
}
public String toString() {
return "SillyDate [year=" + year + ", month=" + month + ", day=" + day + "]";
}
public int year;
public int month;
public int day;
}
You need a class which JAXB can understand, and then write an adapter between that class and the custom class, like this:
public class SillyDateAdapter extends XmlAdapter<XMLGregorianCalendar, SillyDate> {
public SillyDate unmarshal(XMLGregorianCalendar val) throws Exception {
return new SillyDate(val.getYear(), val.getMonth(), val.getDay());
}
public XMLGregorianCalendar marshal(SillyDate val) throws Exception {
return DatatypeFactory.newInstance().newXMLGregorianCalendarDate(val.year, val.month, val.day, 0);
}
}
Now you can use that in your own classes, like this:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement
public class Example2 {
#XmlSchemaType(name = "date")
#XmlJavaTypeAdapter(type=XMLGregorianCalendar.class,value =SillyDateAdapter.class)
public SillyDate publishingDate;
}
There are plenty of good examples of using the #XmlJavaTypeAdapter available on the net, like this one and this one, and several others. Happy adapting!

Categories

Resources