I am using GSON to serialize my hibernate entity.
#Entity
#Table(name = "ACCOUNT", uniqueConstraints = {
#UniqueConstraint(columnNames = { "SECONDARY_LOGINID", "COUNTRY_CODE" }, name = "SECONDAY_LOGIN_UNIQUE") })
#NamedQuery(name = "Account.findAll", query = "SELECT a FROM Account a")
#DynamicUpdate
public class Account extends BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
#OneToMany(mappedBy = "accountIdfk", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Address> addresses;
#OneToMany(mappedBy = "accountIdfk", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Contact> contacts;
}
While converting entity to json, GSON is trying to fetch all the unfetched object. Is there a way we can ignore to fetch untouched entities and only serialize the fields which have been fetched?
Related
I have Entity:
#Data
#Entity
#Table(name = "USERS")
public class User{
#Id
#Column(name = "GUID", nullable = false)
private String guid;
#OneToMany(mappedBy = "user", cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = LAZY)
private List<Role> roles;
#OneToMany(mappedBy = "user", fetch = LAZY, cascade = {CascadeType.ALL})
private List<Person> persons;
And I need clone this entity. I do it like this:
usersRepository.detach(user);
But I can not get roles and persons becaus it LAZY. I use hack:
user.getRoles().size();
user.getPersons().size();
usersRepository.detach(user);
But I do not like it. Can I make it easier?
I am having a particular issue when trying to save a collection of objects with hibernate. It seems that when I have more than one object of the same type, hibernate fails to generate the identifier, so I get a org.hibernate.NonUniqueObjectException .
Example:
App1 --> urls
{strApplicationId:1;URLTypeEntity{strCode:1,strDescription:Reply},strURL:www.address1.com},
{strApplicationId:1;URLTypeEntity{strCode:1,strDescription:Reply},strURL:www.address2.com},
{strApplicationId:1;URLTypeEntity{strCode:2,strDescription:Home},strURL:www.address3.com}
If I do not have two URLs with the same URLTypeEntity on the collection, the error is not triggered
#Entity
#Table(name = "tbl_urls")
public class URLEntity
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="intCode")
private Integer intCode;
private String strApplicationID;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "intType", referencedColumnName = "intCode")
private URLTypeEntity objURLType;
private String strURL;
}
#Entity
#Table(name = "tbl_applications")
public class ApplicationEntity
{
#OneToMany(cascade = CascadeType.ALL, mappedBy = "strApplicationID")
private List<URLEntity> colURLs;
}
ApplicationEntity must also have an id.
The solution was changing the CascadeType from ALL To Merge
#OneToMany(cascade = CascadeType.ALL, mappedBy = "strApplicationID")
Changed To
#OneToMany(cascade = CascadeType.MERGE, mappedBy = "strApplicationID")
everyone i have a question with using annotation #OneToMany/#ManyToOne; is it possible to create one user model with two sets of subjects in this model (conducted for the teacher and attending the student) instead of creating separate student and teacher models? I wrote such a code but when I want to get data about item and user, hibernate crashes the "Stack overflow" error.I will add that I use H2 Database.
User Entity:
#Entity
public class User{
#OneToMany(
mappedBy = "student",
cascade = CascadeType.ALL,
fetch = FetchType.EAGER,
orphanRemoval = true
)
private Set<Item> items = new HashSet<>();
#OneToMany(mappedBy = "teacher",
cascade = CascadeType.ALL,
fetch = FetchType.EAGER,
orphanRemoval = true
)
private Set<Item> carriedItems= new HashSet<>();
}
//id and other data
Item entity:
#Entity
public class Item{
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "student_id", nullable = false)
private User student;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "teacher_id", nullable = false)
private User teacher;
}
//id and other data
Thanks for help #Leviand
Based on your comments, looks like your code and logic needs some rework.
First, use instead of Item pojo two dedicated classes:
#Entity
#Table(name = Studend) // I'm guessing a table name
public class Student{
#JoinColumn(name = "student_id", nullable = false)
private User user;
}
#Entity
#Table(name = Teacher) // I'm guessing a table name
public class Teacher{
#JoinColumn(name = "teacher_id", nullable = false)
private User user;
}
Then since an User can only be connected to a single Teacher or Student, refact that in something like:
#Entity
#Table(name = User) // I'm guessing a table name
public class User{
#OneToOne(
mappedBy = "student",
cascade = CascadeType.ALL,
fetch = FetchType.EAGER,
orphanRemoval = true
)
private Student student;
#OneToMany(mappedBy = "teacher",
cascade = CascadeType.ALL,
fetch = FetchType.EAGER,
orphanRemoval = true
)
private Teacher teacher;
}
Hope this helps :)
I didn't know how to describe my question in the title but I hope it will do.
So here is my situation.
I use hibernate to map my entities to db tables.
I got one entity like this:
#Entity
#Table(name = "EX.EXAMPLE")
public abstract class Entity
{
private CustomEntity customEntity;
public static final String CUSTOM_ENTITY = "customEntity";
#OneToOne(cascade = CascadeType.ALL, mappedBy = CustomEntity.ENTITY, fetch = FetchType.LAZY)
#Fetch(FetchMode.SELECT)
public CustomEntity getCustomEntity()
{
return this.customEntity;
}
}
And my CustomEntity
#Entity
#Table(name = "EX.EXAMPLE2")
public class CustomEntity
{
private Entity entity;
public static final String ENTITY = "entity";
#OneToOne
#JoinColumn(name = "ID_ENTITY", nullable = true)
public Entity getEntity()
{
return this.ntity;
}
}
So here is my question: Is it possible to add another CustomEntity relation to Entity? And how do I map it?
Example what I mean:
#Entity
#Table(name = "EX.EXAMPLE")
public abstract class Entity
{
private CustomEntity customEntity;
public static final String CUSTOM_ENTITY = "customEntity";
private CustomEntity customEntity2;
public static final String CUSTOM_ENTITY2 = "customEntity2";
#OneToOne(cascade = CascadeType.ALL, mappedBy = CustomEntity.ENTITY, fetch = FetchType.LAZY)
#Fetch(FetchMode.SELECT)
public CustomEntity getCustomEntity()
{
return this.customEntity;
}
#OneToOne(cascade = CascadeType.ALL, mappedBy = CustomEntity.ENTITY, fetch = FetchType.LAZY)
#Fetch(FetchMode.SELECT)
public CustomEntity getCustomEntity2()
{
return this.customEntity2;
}
}
I only managed it by changing customEntity to a list in Entity.
Greetings
Yes, that is perfectly normal situation. You just need two fields with different mappedBy`, one for each relation
#OneToOne(cascade = CascadeType.ALL, mappedBy = CustomEntity.ENTITY1, fetch = FetchType.LAZY)
#Fetch(FetchMode.SELECT)
public CustomEntity getCustomEntity()
{
return this.customEntity;
}
#OneToOne(cascade = CascadeType.ALL, mappedBy = CustomEntity.ENTITY2, fetch = FetchType.LAZY)
#Fetch(FetchMode.SELECT)
#JoinColumn(name = "entity_2_id")
public CustomEntity getCustomEntity2()
{
return this.customEntity2;
}
And two fields in CustomEntity, one for each mapping
#OneToOne
#JoinColumn(name = "ID_ENTITY_1", nullable = true)
public Entity getEntity1()
{
return this.entity1;
}
#OneToOne
#JoinColumn(name = "ID_ENTITY_2", nullable = true)
public Entity getEntity2()
{
return this.entity2;
}
I use the single table strategy (with discriminator) to use inheritance
UML schema => http://yuml.me/67acf6a6
I would like to fetch all the orders of a customer with all the associations related (cars, books and tvs). Do you know how to achieve this without breaking the model classes.
#Entity
#Table(name = "customers")
public class Customer{
private Date birthDate;
private String name;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "customer", cascade = CascadeType.ALL, orphanRemoval = true)
#OrderBy("order")
private List<? extends Order> orders;
}
#Entity
#Table(name = "orders")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
public abstract class Order{
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#NotNull
#JoinColumn(name = "CustomerID")
private Customer customer;
}
#Entity
#DiscriminatorValue("book")
public class BookOrder extends Order {
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
#JoinColumn(name="book_id")
private Set<Book> books;
}
#Entity
#DiscriminatorValue("car")
public class CarOrder extends Order {
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
#JoinColumn(name="car_id")
private Set<Car> cars;
}
#Entity
#DiscriminatorValue("tv")
public class TvOrder extends Order {
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
#JoinColumn(name="tv_id")
private Set<Tv> tvs;
}
If I'm doing in HQL
select cutomer from customer customer
inner join fetch customer.orders order
left join fetch order.cars
left join fetch order.books
left join fetch order.tvs
I'm getting the error
org.hibernate.QueryException: could not resolve property: cars,
It makes sense in the abstract class Order this field doesnt exist.
Do you know how i can achieve this ? what is the recommendation of hibernate in this case ?
My goal is to simple a simple query and to fetch everything.
If you do the following query
select c from customer c
join fetch c.orders
then you retrieve all the customers with any types of the orders (cars | books | tvs). Those orders are polymorphic, if do instanceof for each Customer.orders element you can determine what type of order element is.