I'm building an application with Google App Engine. I'm using Objectify for Datastore persistence. I have two POJO class.
#Entity
public class Book
{
#Id private Long id;
private String name;
private String isbn;
private String author;
}
and
#Entity
public class Person {
#Id private String email;
private String password;
private String name;
private List<Book> myBooks;
}
A person can contain many books but book only belongs to one person. Currently I'm saving data like this.
//data from Front-end
Person p = new Person(email, password, name);
PersonDAO dao = new PersonDAO();
dao.save(p);
//...
//data from Front-end
Book b = new Book(name, author, isbn);
BookDAO daoBook = new BookDAO();
daoBook.save(b);
//...
Person q = dao.load(email);
q.addBook(b);
dao.save(q);
ObjectifyService ofy() with methods are implemented in DAO classes.
It's ok my implementation? How can I optimize the relationship? Every time that I need create a book this is saved like Entity but I need the relationship with a person, therefore I'm saving book twice. I've seen implementantions with Key, Ref #Load tags but I don't know how are working them.
Besides, Person POJO has a Date field. will It be saved normally?
It has being quite a while since I wrote this code, but here it goes:
#Entity
public class Book {
#Id
private Long id;
#Parent
#ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
private Key<User> user;
private String author;
private String isbn;
private String name;
}
Take a look at Udacity Conference Central for full example. It is the final project of Developing Scalable Apps in Java
with Google App Engine, by Udacity.
Related
Let's say I have two entities:
#Entity
public class Phone {
#Id
private Long id;
private String number;
}
#Entity
public class Person {
#Id
private Long id;
private String name;
}
The relationship between a person and a phone is one to one.
How could I access only the phone's number in the Person entity mapped by the phone's id
#Entity
public class Person {
#Id
private Long id;
private String name;
// ???
private String phoneNumber;
}
The reason for not mapping the whole entity is because in some more realistic entities there are too many properties.
I don't think you can, but something like this might be acceptable:
public class Person {
#OneToOne
#JoinColumn(name = "phone_id")
private Phone phone;
public String getPhoneNumber() {
return phone.getNumber();
}
}
Although you have mapped the whole object, not just the single property, you have only exposed the single property you want. The other stuff is hidden.
Alternatively, do it at the DB layer using a View:
create view person_with_phone as
select p.id, p.name,f.number
from person p
join phone f on f.id=p.phone_id
and then have an entity class to match the view. You'll need to turn off schema creation in your JPA implementation.
I am making a simple CRUD application using Spring boot and MongoDB, the problem that I am facing is that I don't know how to define the model classes.
My application should be like this:
A site has some characteristics such as an ID, region, city, ... and contains 4 parts (cellulars) that each has its own characteristics. Any help would be appreciated.
This is what I have so far:
public class Site {
#Id
String siteId;
String projectPhase;
String region;
String city;
String siteName;
String newSiteName;
String clusterName ;
String longitude ;
String lattitude ;
#OneToMany(mappedBy = "siteId")
List L;
What I want to know is how do I associate another class inside this one.
Annotations like #OneToMany are typically used within JPA-context, and are unnecessary when using Spring Data MongoDB. This is also mentioned by the documentation:
There’s no need to use something like #OneToMany because the mapping framework sees that you want a one-to-many relationship because there is a List of objects.
You have a few options when you want to define one-to-many relations when using MongoDB. The first of them is to define them as embedded objects within the same document:
#Document
public class Site {
#Id
private String id;
private String city;
private String region;
private List<Part> cellulars;
}
public class Part {
private String characteristic1;
private String characteristic2;
}
This means that the parts do not exist on their own, so they don't need their own ID either.
Another possibility is to reference to another document:
#Document
public class Site {
#Id
private String id;
private String city;
private String region;
#DBRef
private List<Part> cellulars;
}
#Document
public class Part {
#Id
private String id;
private String characteristic1;
private String characteristic2;
}
In this case, parts are also separate documents, and a site simply contains a reference to the part.
Background:
I am trying to model a many-to-many relationship using the embedded document model.
The reason behind choosing mongodb is because the schema is dynamic as the platform deals with various products and services.
The application when logged in by an user bootstraps all the information of a user. But, all the queries such as update,search are majorly done on the products and services associated with users on the platform.
Problem Statement:
#Getter
#Setter
#ToString(exclude = { "id", "password" })
#Document(collection = "users")
public class User implements Serializable {
#Id
private ObjectId id;
#Indexed(unique = true)
private String username;
private String password;
private String email;
private String mobile;
private Sex sex;
private List<String> tags;
}
public class Product {
#Id
private String id;
private String name;
private double price;
private List<User> users;
}
public class Service{
#Id
private String id;
private String name;
private double price;
private List<User> users;
}
Initially i thought of making users as embedded documents within products and services. The reason behind choosing the embedded document design is to avoid multiple queries during the search.
But, I also realized that when a user logs in to the application i need to have all the user related information which needs to be bootstrapped. The design seems to be getting complicated.
I would like to understand if this scenario could be handled in a better way. Anyone who has already solved this situation?
The queries i would like to perform are
Find:
db.products.find({"name": /.*m.*/})
Update:
.update(Products:{$elemMatch:{Bag:"charollette"}}, {$set: {'Products.$.Name':"Charollette blue"}});
Insert:
db.products.insertOne( { item: "card", qty: 15 } );
I have a composite object that I wish to store in mongodb (using spring annotations). The object is as follows:
#Document(collection="person")
class Person {
#Id
private String id;
private Address address;
private String name;
}
and the composite class Address:
#Document
class Address {
#Indexed
private Long countryId;
private String street;
#Indexed
private String city
}
I need both country and city to be indexed as part of the person collection. Alas, no index is created for them. Any ideas how to create the index?
I have tried the following which works but is not elegant:
#Document(collection="person")
#CompoundIndexes({
#CompoundIndex(name = "countryId", def = "{'address.countryId': 1}")
})
class Person {
You can set up multiple secondary indexes, if you wish. This would be a good place to start.
How to load two attributes of reference document/entity using morphia
I have a Class Person and School like this
person class
#Entity
public class Person {
#Id private ObjectId id;
private String name;
#Embedded private PersonEducation schoolInfo;
}
#Embedded
public class PersonEduction {
#Reference private School school;
private String year;
private String degree;
}
School Class
#Entity
public class School {
#Id private ObjectId id;
private String name;
private String address;
private String description;
}
How I can get id and and name fields of School in Person class
example
When i want to person
Person person = datastore.find(Person.class).field("name").equals("xyz").get();
person.gerSchoolInfo();
Response (Not want all School class fields)
{school:{_id:ObjectId("4fcef3e20364a375e7631fb0"), name:"SchoolA"}, year:"1990", degree:"MBA" }
and If I query school where _id=ObjectId("4fcef3e20364a375e7631fb0"), I get all School fields
{_id:ObjectId("4fcef3e20364a375e7631fb0"), name:"xyz", address="some add", description="some desc"}
Instead of using #Reference you should use
key<School> school;
and use custom query to load it.
datastore.createQuery(School.class).retrivedFields(true, "id","name");
To give an alternative to mtariq, replace
#Reference private School school;
with
private ObjectId schoolId;
and fetch it yourself. However since your School class is so simple I think you'd be better off using Lazy loading, so:
#Reference #Lazy private School school;
This will only load the school object when/if it is referenced.