Room one-to-many warning - java

When creating my contact DAO and related classes, I am getting the following error:
The query returns some columns [mContactId, mAddress, mPostcode, mCity, mCountry, mAddressType]
which are not used by org.linphone.contacts.managementWS.ContactWithAddresses. You can use
#ColumnInfo annotation on the fields to specify the mapping.
org.linphone.contacts.managementWS.ContactWithAddresses has some fields [mName, mSurname,
mFullName, mCompany, mNote, mIsBlocked] which are not returned by the query. If they are not
supposed to be read from the result, you can mark them with #Ignore annotation. You can suppress
this warning by annotating the method with #SuppressWarnings(RoomWarnings.CURSOR_MISMATCH).
Columns returned by the query: id, mContactId, mAddress, mPostcode, mCity, mCountry,
mAddressType. Fields in org.linphone.contacts.managementWS.ContactWithAddresses: id, mName,
mSurname, mFullName, mCompany, mNote, mIsBlocked.
In my ContactsDao:
#Query("SELECT * FROM contacts_table")
List<Contact> getAll();
#Transaction
#Query("SELECT * FROM phone_numbers_table")
List<ContactWithNumbers> getContactsWithPhoneNumbers();
ContactsWithNumbers.java:
#Embedded public Contact contact;
#Relation(parentColumn = "id", entityColumn = "mContactId", entity = PhoneNumbers.class)
public List<PhoneNumbers> numbers;
And below is my Contact.java:
#Entity(tableName = "contacts_table")
public class Contact {
// TODO - members should be private, not public. Changed to workaround error.
#PrimaryKey(autoGenerate = true)
public int id;
/* String resource ID for the user name */
#SerializedName("first_name")
public String mName;
/* String resource ID for the user surname */
#SerializedName("last_name")
public String mSurname;
/* String resource ID for the user's full name */
#SerializedName("full_name")
public String mFullName;
/* String resource ID for the user company */
#SerializedName("company")
public String mCompany;
/* String resource ID for the user's phone number(s) */
/** String resource ID for the user's note */
#SerializedName("note")
public String mNote;
#SerializedName("blocked")
public boolean mIsBlocked;
/**
* #param firstName
* #param lastName
* #param fullName
* #param company
* #param note
* #param isBlocked
*/
#Ignore
public Contact(
String firstName,
String lastName,
String fullName,
String company,
String note,
boolean isBlocked) {
super();
this.mName = firstName;
this.mSurname = lastName;
this.mFullName = fullName;
this.mCompany = company;
this.mNote = note;
this.mIsBlocked = isBlocked;
}
public Contact(String name, String surname, String company, String note, boolean isBlocked) {
this.mName = name;
this.mSurname = surname;
this.mCompany = company;
this.mNote = note;
this.mIsBlocked = isBlocked;
}
public int getId() {
return id;
}
public String getmName() {
return mName;
}
public String getmSurname() {
return mSurname;
}
public String getmFullName() {
return mName + " " + mSurname;
}
public String getmCompany() {
return mCompany;
}
public String getmNote() {
return mNote;
}
public boolean getmIsBlocked() {
return mIsBlocked;
}
}
It is quite likely that I have not fully grasped the concept of Room one-to-many relations, but what exactly am I doing wrong here and getting that warning?

It's say very clear: You can use #ColumnInfo annotation on the fields to specify the mapping.
Change your code like this:
#NonNull
#PrimaryKey
#ColumnInfo(name = "id")
private String id;
More at codelab: https://codelabs.developers.google.com/codelabs/android-room-with-a-view/#0

Related

Android - Structure of classes for DB Tables + POJO Class can be same?

I have 25+ tables and I have used Content Provider with Database.
I have created separate files for each tables with following structure:
TProductUnit.java in package of com.myapp.db.tables
public class TProductUnit {
/***
* Fields of TABLE_PRODUCT_UNIT Table
***/
public static final String TABLE_PRODUCT_UNIT = "product_unit";
/**
* Columns of TABLE_PRODUCT_UNIT
*/
public static final String PRODUCT_UNIT_SERVER_ID = "id";
public static final String PRODUCT_UNIT_NAME = "name";
public static final String PRODUCT_UNIT_ITP = "itp";
public static final String PRODUCT_UNIT_UTP = "utp";
public static final String PRODUCT_UNIT_STATUS = "status";
public static String[] PRODUCT_UNIT_COLUMNS = new String[] {
BaseColumns._ID,
PRODUCT_UNIT_SERVER_ID,
PRODUCT_UNIT_NAME,
PRODUCT_UNIT_ITP,
PRODUCT_UNIT_UTP,
PRODUCT_UNIT_STATUS
};
}
ProductUnit.java is POJO class which will helpful when First time get data from Server.
public class ProductUnit {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("product_id")
#Expose
private Integer productId;
#SerializedName("url")
#Expose
private String url;
#SerializedName("bit")
#Expose
private int bit;
#SerializedName("status")
#Expose
private Integer status;
#SerializedName("itp")
#Expose
private String itp;
#SerializedName("utp")
#Expose
private String utp;
/**
* #return The id
*/
public Integer getId() {
return id;
}
/**
* #param id The id
*/
public void setId(Integer id) {
this.id = id;
}
public Integer getProductId() {
return productId;
}
public void setProductId(Integer productId) {
this.productId = productId;
}
public int getBit() {
return bit;
}
public void setBit(int bit) {
this.bit = bit;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
/**
* #return The status
*/
public Integer getStatus() {
return status;
}
/**
* #param status The status
*/
public void setStatus(Integer status) {
this.status = status;
}
/**
* #return The itp
*/
public String getItp() {
return itp;
}
/**
* #param itp The itp
*/
public void setItp(String itp) {
this.itp = itp;
}
/**
* #return The utp
*/
public String getUtp() {
return utp;
}
/**
* #param utp The utp
*/
public void setUtp(String utp) {
this.utp = utp;
}
/**
* Convenient method to get the objects data members in ContentValues object.
* This will be useful for Content Provider operations,
* which use ContentValues object to represent the data.
*
* #return
*/
public ContentValues getContentValues() {
ContentValues values = new ContentValues();
values.put(PRODUCT_UNIT_SERVER_ID, id);
values.put(PRODUCT_UNIT_NAME, name);
values.put(PRODUCT_UNIT_ITP, itp);
values.put(PRODUCT_UNIT_UTP, utp);
values.put(PRODUCT_UNIT_STATUS, status);
return values;
}
}
Both classes have most of the same number of fields with same values if we think about #SerializedName
Problem:
Whenever I need to add some fields in any Particular Table then I have to add in all Table file and JSON POJO Class too.
When any field name changed by server side then I have to change in both file.
My Question is: Is there any better solution for this optimization. Have you ever manage like this?
P.S. I have 25+ tables so I have to create 50+ classes.
Help please. Thanks.

How to get an Entity for which a users key is held in?

So basically I want to get the store which a Person is in? Here is the Pojo code for the store ;
#Entity
public class Store{
#Id
Long StoreId;
String Name;
String Address;
#Index List<Key<Person>> Members;
private House() {
}
public Store(Long StoreId ,String Name, String Address) {
StoreId = StoreId;
this.Name = Name;
this.Address = Address;
Members = new ArrayList<Key<Person>>();
}
public Long getId() {
return StoreId;
}
public String getName() {
return Name;
}
public void setName(String name) {
this.Name = name;
}
public String getAddress() {
return Address;
}
public void setAddress(String postcode) {
this.Address = Address;
}
public void AddToStore(Key<Person> person) {
Members.add(person);
}
Here is the code that Creates a store and adds in the current signed in user (Google login)
/**
* Inserts a new {#code Store}.
*/
#ApiMethod(
name = "insert",
path = "Store",
httpMethod = ApiMethod.HttpMethod.POST)
public House insert(User user) throws UnauthorizedException {
if (user == null){
throw new UnauthorizedException("You need to authorisation");
}
String tempName = "cottages";
String tempAddress = "Gogoland";
String userId = user.getUserId();
Key<Person> personKey = Key.create(Person.class, userId);
final Key<Store> storeKey = OfyService.factory().allocateId(Store.class);
final Long StoreId = storeKey.getId();
Store h = new Store(StoreId , tempName,tempAddress);
h.AddToStore(personKey);
ofy().save().entity(h).now();
logger.info("Created Store.");
return ofy().load().entity(h).now();
}
So the relationship between Store to person is one to many as you can see. So i want to be able to get the Current house of the logged in user and in turn retrieve the other "person"/members entities also in the object. Furthermore i would wish to also retrieve the "children" of the "Person" entities on the same store as the current user.
Furthermore How would it be possible to invite other people to join the users store via email?
Any help is appreciated.
You should filter by key since you have an index:
return ofy().load().filter("Members", personKey).first().now();
However if you already saved the entity with the .save() method, you can simply do this:
return h;

JPA- Showing User Role relationships with Many to Many Hashset ENUMs

My DTO is being stored using JPA Hibernate and I'm able to store the other fields but having trouble trying to store this relationship for the user. The userRoleSet HashSet has ENUMs that represent what roles that user has. Some users with have no roles while someone will have 1 to 3 roles. Each role is different. How would I got about representing this in my database and using JPA? At the moment, the #ManyToMany doesn't work, I miss be missing something else? Essentially, I need to be able to query that specific user in the database and have it return the roles that is assigned to that user.
UserType Enums
public enum UserType
{
ALPHA,BRAVO,CHARLIE
}
Default User DTO JPA
#Entity
#Table(name = "users")
public class DefaultUser implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_id")
private long user_id;
#Column(name = "user_name")
private String user_name;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "password")
private String password;
#ManyToMany
private Set<UserType> userRoleSet = new HashSet<UserType>();
/**
* #return the userTypes
*/
public Set<UserType> getUserTypes()
{
return userRoleSet;
}
/**
*
* #param userTypes
* the userTypes to set
*/
public void setUserTypes(Set<UserType> userTypes)
{
this.userRoleSet = userTypes;
}
/**
* #return the user_id
*/
public long getUser_id()
{
return user_id;
}
/**
* #return the user_name
*/
public String getUser_name()
{
return user_name;
}
/**
* #return the firstName
*/
public String getFirstName()
{
return firstName;
}
/**
* #return the lastName
*/
public String getLastName()
{
return lastName;
}
/**
* #return the password
*/
public String getPassword()
{
return password;
}
/**
* #param user_id
* the user_id to set
*/
public void setUser_id(long user_id)
{
this.user_id = user_id;
}
/**
* #param user_name
* the user_name to set
*/
public void setUser_name(String user_name)
{
this.user_name = user_name;
}
/**
* #param firstName
* the firstName to set
*/
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
/**
* #param lastName
* the lastName to set
*/
public void setLastName(String lastName)
{
this.lastName = lastName;
}
/**
* #param password
* the password to set
*/
public void setPassword(String password)
{
this.password = password;
}
}
The #ManyToMany annotation is used to map an association between two entities. For collections of simple types, the annotation to use is #ElementCollection.
PS: you always read and post the complete and exact error message you get when something "doesn't work".

Hibernate saveOrUpdate does not update

I am trying to update a table row using the session.saveOrUpdate() method in Hibernate.
However, it is unable to update the row and tries to save it by producing an insert statement. This insert does not work due to a few non-nullable fields in my DB.
I am able to retrieve the Id of the object to be saved at the DAO layer, so I am not able to understand why it doesn't just update the corresponding row in the DB table.
Bean Class: (BaseEntityBean has the Id, CreatedBy, etc.)
public class EmployeeMasterBean extends BaseEntityBean {
/**
*
*/
private static final long serialVersionUID = 1L;
#Column(name = "FirstName", nullable = false)
private String firstName;
#Column(name = "LastName", nullable = false)
private String lastName;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "Dob", insertable = true, updatable = true, nullable = false)
private Date dateOfBirth;
#Column(name = "Email", length = 100)
private String email;
#Column(name = "PhoneNumber", nullable = false)
private String phoneNumber;
#Column(name = "Address1", nullable = false)
private String address1;
#Column(name = "Type", nullable = false)
private Short employeeType;
#Column(name = "Gender", nullable = false)
private Short gender;
/**
* #return the firstName
*/
public final String getFirstName() {
return firstName;
}
/**
* #param firstName the firstName to set
*/
public final void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* #return the lastName
*/
public final String getLastName() {
return lastName;
}
/**
* #param lastName the lastName to set
*/
public final void setLastName(String lastName) {
this.lastName = lastName;
}
/**
* #return the dateOfBirth
*/
public final Date getDateOfBirth() {
return dateOfBirth;
}
/**
* #param dateOfBirth the dateOfBirth to set
*/
public final void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
/**
* #return the email
*/
public final String getEmail() {
return email;
}
/**
* #param email the email to set
*/
public final void setEmail(String email) {
this.email = email;
}
/**
* #return the phoneNumber
*/
public final String getPhoneNumber() {
return phoneNumber;
}
/**
* #param phoneNumber the phoneNumber to set
*/
public final void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
/**
* #return the address1
*/
public final String getAddress1() {
return address1;
}
/**
* #param address1 the address1 to set
*/
public final void setAddress1(String address1) {
this.address1 = address1;
}
/**
* #return the employeeType
*/
public final Short getEmployeeType() {
return employeeType;
}
/**
* #param employeeType the employeeType to set
*/
public final void setEmployeeType(Short employeeType) {
this.employeeType = employeeType;
}
/**
* #return the gender
*/
public final Short getGender() {
return gender;
}
/**
* #param gender the gender to set
*/
public final void setGender(Short gender) {
this.gender = gender;
}
}
DAO Method:
public EmployeeMasterBean saveOrUpdateEmployee(EmployeeMasterBean employeeMasterBean) throws Exception{
Session session = null;
Transaction tx = null;
try {
session = HibernateUtil.getSessionFactory().openSession();
tx = session.beginTransaction();
session.saveOrUpdate(employeeMasterBean);
tx.commit();
} finally {
session.close();
}
return employeeMasterBean;
}
Eclipse debugger exceptions thrown are:
could not insert: [com.indven.gpil.hrd.entity.EmployeeMasterBean]
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'CreatedBy' cannot be null
As the error message say, the database has a column createdby which can't be null.
When you called saveOrUpdate() someone has set this property to null so the update isn't possible.
I think CreatedBy column is present in DB table as notnull but your bean does not have this column mapped, hence a null value is sent when you do a saveOrUpdate, which causes Above exception to be thrown.
Either add a mapping to CreatedBy in your bean with some default value and let trigger etc can update the default value. Or if you can change the column to be nullable in Database
The bean did not have the rowVersion property (for optimistic locking) set, and hence by default it was null. Hibernate thus interpreted this as a new record, and kept saving it.
I fixed it by storing the row version in my Value Object and the corresponding Bean whenever I attempted to save or update any records.
we can add the following to jsp form to match with entity PK (id),
<form:hidden path="id" />

I dont want to save the field with null values in MongoDB using Morphia

I have a form with many fields, I want to save this fields in mongodb in a collection. I want if the user doesnt fill a textfield, then this field should not be saved in the collection.
I have an District Entity. This entity contains another two entities (contact and address).
The District class lokks like this:
public class District {
#Id private ObjectId id;
private String Type;
private String Name;
private Contact contact;
private Address address;
/**
* #return the Type
*/
public String getType() {
return Type;
}
....
/**
* #param Type the Type to set
*/
public void setType(String Type) {
this.Type = Type;
}
For contact I have this Java class:
#Embedded
public class Contact {
private String email;
private String fax;
private String firstname;
private String lastname;
private String gender;
private String telephone;
private String title;
/**
* #return the email
*/
public String getEmail() {
return email;
}
/**
* #param email the email to set
*/
public void setEmail(String email) {
this.email = email;
}
/**
* #return the fax
*/
public String getFax() {
return fax;
}
/**
* #param fax the fax to set
*/
public void setFax(String fax) {
this.fax = fax;
}
...
and my form lokks like this:
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
Mongo mongo = null;
try {
mongo = new Mongo();
} catch (UnknownHostException ex) {
Logger.getLogger(TestForm.class.getName()).log(Level.SEVERE, null, ex);
}
Morphia morphia=new Morphia();
morphia.map(District).map(Contact).map(Address);
District district=new District();
district.setName(jTextField2.getText());
district.setType(jTextField3.getText());
Address address=new Address();
address.setCity(jTextField11.getText());
address.setStreet(jTextField10.getText());
address.setZipcode(jTextField9.getText());
....
Datastore ds=morphia.createDatastore(mongo, "rcfdb");
ds.save(district);
I want if the user doesnt fill the Name field in the Form, then this field is not written in the MongoDB.(now I see the field i.e Name with null value) I have tried to do that but that didnt help me:
....
if(jTextField4.getText()!="")
{
contact.setName(jTextField4.getText());
}
....
could you please help me to do this job?
thanks
Use String#equals to compare String content. The == operator compares object references. JTextField#getText returns a different String object compared to the interned one "" being compared so the field value for the Entity contact is never set.
if (jTextField4.getText().equals("")) {
contact.setName(jTextField4.getText());
}
One can disable storing of null values in mongo by using Datastore.getMapper().getOptions().setStoreNulls(false);

Categories

Resources