What is Entity Class? - spring

I'm trying to use MongoTemplates find method. It wants "entity class" as the second parameter.
I give the model class for this, but it does not accept it. It also doesn't show the #Entity annotation. The method is as follows:
mongoTemplate.find(queryBuy , Orders, "orders");
Orders is my model class and orders is collections name. Here are the annotations at the beginning of my model class
#Getter #Setter
#Document(collection = "orders")
#Data
#JsonIgnoreProperties(ignoreUnknown = true)
public class Orders {
....
}

MongoTemplate find() methods has as the second argument a [Class][1]. You can get a Class instance with Orders.class. Having said this, please try the following:
mongoTemplate.find(queryBuy, Orders.class, "orders");

Related

Spring: combine JPA Derived query methods and query by example

Is it possible to use JPA derived methods and query by example at the same time?
Let's imagine i have two entities like this:
#Entity
#Data
public class Person {
#Id
#GeneratedValue
Long id
String name;
String surname;
#OneToMany
List<Dog> dogs;
}
#Entity
#Data
public class Dog{
#Id
#GeneratedValue
Long id
String name;
}
I'd like to be able to do something like this (just an example):
Person p = new Person ();
p.setName("Mario");
personRepository.findDistinctByDogsIsNotNull(Example.of(p));
The Example.of(p) only works if i do findAll, but it doesn't work if i define inside the repository a method like this
private interface PersonRepository extends JpaRepository<Person, Long>{
List<Person> findDistinctByDogsIsNotNull(Example<Person> example)
}
The error it gives me is something like this:
Failed to create query for method public abstract java.util.List dev.cele.test.repository.PersonRepository.findDistinctByDogIsNotNull(org.springframework.data.domain.Example)! At least 1 parameter(s) provided but only 0 parameter(s) present in query.
So my question is: is it possible to do a query by example in a JPA derived query method?
And if it's not possible how can i create some sort of parametrizable query that also has a predetermined condition?

Hibernate - #ManyToOne on Entities that extends from Abstract class

I have a similar structure already existing in my database and it has many data:
#MappedSuperclass
public abstract class Person {
#Id
Long id;
#Column(name="COMMONFIELD")
String commonField;
}
#Entity
#Table(name = "WOMAN")
public class Woman extends Person {
.....
}
#Entity
#Table(name = "MAN")
public class Man extends Person {
.....
}
This code will work with two different tables WOMAN and MAN where both will contain the common fields defined in the abstract class Person.
Now I will like to have a class Car that has an owner which can be either a woman or a man. A person can also be the owner of several cars. So I declare it like this:
#Entity
#Table(name = "CAR")
public class Office {
....
#ManyToOne
#JoinColumn(name = "IDPERSON")
Person owner;
}
The issue I encounter is that I cannot create an attribute linked to a Mapped-Superclass.
Of course, I could solve this issue simply by defining Person as an entity and declaring it to be InheritanceType.SINGLE_TABLE and Woman and Man with a discriminator this way they could share the same table and it will work. However, this solution is not possible for me because the data is already there and there are many dependencies from it, so I cannot change the WOMAN or MAN table.
Is there a way to use a discriminator in this case too, so that Hibernate will know in which table it has to look for the person?
Thank you very much in advance.
So I couldn't find any way to tell hibernate to use a discriminator on a specific attribute.
So what I did, I created a Gender Enum
enum Gender {
WOMAN, MAN;
}
And I added it as an attribute of a Car. I also wired the woman and the man service and created a getter method for the owner that will decide which service to use based on gender.
#Entity
#Table(name = "CAR")
public class Office {
....
#Column(name = "PERSONID")
Long personId;
#Column(name = "GENDER")
Gender gender;
#Autowired
#Transient
WomanService womanService;
#Autowired
#Transient
ManService manService;
Optional<Person> getOwner(){
switch(gender){
case WOMAN: return womanService.findById(personId);
case MAN: return manService.findById(personId);
default: return Optional.empty();
}
}
}
I'm aware this solution sucks but it's the best I could come up with to avoid redefining other entities.

How to override the type of a mapped column of a superclass in childclass JPA

I'm using spring boot and Hibernate.
What I'm trying is to have a single table for Materials and one for Costs.
What I want to know is if there's a way to specify in a subclass of Cost the specific type of material (Subclass of Material) it should handle. In the end, what I will like is that in order to create a SpecificCost, a SpecificMaterial should be provided not just a general Material.
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Material {}
#Entity
public class SpecificMaterial extends Material {}
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Cost {
#ManyToOne
private Material material;
}
#Entity
public class SpecificCost extends Cost{
/*
* I want to be able to specify that the field "material"
* that comes from the parent class
* should be of type SpecificMaterial a subclass of Material
*/
}
I tried to solve this with generics but it's not possible to use genetics in mapped columns.
I have also tried with every one of the inheritance schemes but I haven't been able to.
Does anyone know if there's a way to accomplished what I'm trying here?

Multi table association with Spring data JPA

I'm trying to create DB solution for my Customer Offer requirement. I have to read a file and store the data in multiple tables which are mostly associated to each other.
I've created Entity classes and their associations as below. But with the current approach I see an issue expanding the offers from Coupons to Rewards. If I create another entity for Rewards then I need to update my CustomerEntity class and add another #OneToMany association with the new entity.
#Entity(name = "METADATA")
public class MetadataEntity {
Metadata Id
Offer description
//Setters & Getters
}
#Entity(name = "CUSTOMER")
public class CustomerEntity {
Customer Id
Customer Name
CouponEntity (OneToMany - Join column Coupon Code)
//Setters & Getters
}
#Entity(name = "PROFILE")
public class ProfileEntity {
Profile Id
CustomerEntity (OneToOne - Join Column Customer Id)
//Setters & Getters
}
#Entity(name = "COUPON")
public class CouponEntity {
Coupon Code
Amount
Expiry
//Setters & Getters
}
#Entity(name = "OFFER")
public class OfferEntity{
Id
MetadataEntity(ManyToOne - Join column Metadata Id)
ProfileEntity(ManyToOne - Join column Profile Id)
//Setters & Getters
}
And from my DAO class I'm using OfferRepository class associated with Offer.
#Repository
public interface OfferRepository extends JpaRepository<OfferEntity, String> {}
#Autowired
OfferRepository offerRepo;
public class DaoImpl {
createOffer(OfferEntity offer){
offerRepo.save(offer);
}
readOffers(){
offersList = offerRepo.findAll();
for-each offer:offersList {
//access all customer information & offer information (could be a coupon or rewards)
offer.getProfile().getCustomer().getCoupons();
}
}
}
I'm trying to identify a solution where I don't need to update any of my existing entity classes in if I'm expanding the Offers.
I would suggest you create a base class for Coupon and Rewards. Let's call it Benefit.
This can then be used as the relationship in the Customer class.
The customer class then could have a method to get either Coupons or Rewards depending on the class object you pass to that method like:
T List<T> getBenefits(Class<T> type)

ID field is null in controller

I am using spring mvc with hibernate and JPA. I have a Person class which is inherited by another class called Agent. The mapping is implemented as follows:
#Entity
#Table(name = "Person")
#Inheritance(strategy = InheritanceType.JOINED)
public class Person extends Auditable implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "PersonId")
protected Long id;
//other variables
...
}
#Entity
#PrimaryKeyJoinColumn(name = "PersonId")
public class Agent extends Person implements Serializable {
//additional agent specific variables go here
...
}
Saving new data is smooth and I have no problem there. however, when I edit data, everything except the id value is bound to the controller method's model attribute. I have verified that the id has been sent along with other items from the browser using chrome's developer tools. but the id field at the controller is always null and as a result the data is not updated. This is what my controller method looks like:
#RequestMapping(value = "register", method = RequestMethod.POST)
public #ResponseBody CustomAjaxResponse saveAgent(ModelMap model, #ModelAttribute("agent") #Valid Agent agent, BindingResult result) {
...
}
I suspect the problem is probably with my inheritance mapping because I have other classes inheriting from the Person class and I face a similar problem there as well.
Please help!
you need a public setter for id.
In cases like this I commonly use a specific dto for the form, and/or implement a conversion service that retrieves the entity via hibernate based on id and then performs a merge.

Resources