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.
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.
So, I have one #Document class which has a embedded pojo field which I want it to be unique for the document based on a key in the pojo class. I tried using #CompoundIndex & #Indexed to mark it as unique but it doesn't seem to work.
#Document
public class Project {
private String id;
private String name;
private List<Details> details = new ArrayList<>();
}
public class Details{
private String key;
private String description;
}
What I want to achieve is that a project document should have unique details field in it with it's key being unique. But when I have the
#CompoundIndexes({ #CompoundIndex(name = "details_key", def = "{'details.key':1}", unique = true) }) on the Project class it doesn't work. Which I thought it should. Or am I wrong somewhere with my understanding. As I am new to this.
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.
i'm curious about how HQL would assert equality between an entity instances.
Let's say I have a Entity called Person
#Entity
public class Person{
#Id
private Long id;
private String name;
}
and Department
#Entity
public class Department {
#Id
private Long id;
#ManyToOne
private Person person;
}
then it's fine if I do the following statement:
Query query = getSession().createQuery("from Department d where d.person = ?");
query.setProperty(0,new Person(1L));
but, what if I have an Embedded entity and no pk defined? like
#Embeddable
public class Adress {
private String email;
private String street;
private Long identifier;
}
#Entity
public class Person{
#Id
private Long id;
private String name;
#Embedded
private Address address;
}
would have any way so I could tell JPA to make it work:
Query query = getSession().createQuery("from Person p where p.address = ?");
query.setProperty(0,new Address(1L));
even though it's not exactly a primary key?
For sure i know i'd work if I tried p.adress.identifier, and then passed just the Long value, but the point is, can I tell JPA provider how it's gonna kind of 'implement' equality my way?
Thank you all
No, it is not supported and it would be difficult in general or would not make sense in some situations, like when there are collections in the Embeddable.
If you find that you need this often though, consider converting such Embeddables to custom user types. Then you can perform comparisons the way you described.
I am using hibernate for database communication. I have one class as:
#Table(name="Person")
public class Person {
#Column(name="name")
private String name;
#OneToMany
#JoinColumn(name="Address_id)
private Set<Address> address;
... <other filed similarly>
}
Now I want to get this object using its primary key , but object should have only specific columns populate?
I tried using criteria and projection, it is returning a result but it is not mapped to Object i expect (Person Object)
Any idea how to solve this problem using hibernate query/criteria?
Thanks
The hibernate annotations used have to be correctly written.
Let assume that you have two Entities: Person and Address.
#Table(name="Person")
public class Person {
#Column(name="name")
private String name;
#OneToMany
#JoinColumn(name="Address_id")
private Set<Address> address;
... <other filed similarly>
}
And on the other side you have Address class
#Table(name="addresses")
public class Address{
#Column(name="name")
private String addressName;
#ManyToOne
private Person person;
}
Using this mapping when you have a method like:
public Encounter getAddressById(int idAddress) {
session = sf.getCurrentSession();
session.beginTransaction();
Address address = (Address ) session.load(Address .class, idAddress);
return address ;
}
This should return the address mapped with person; and the display of some columns will choosen by you because hibernate here returned the entire object.