I have 3 tables in my database, container, item and item_container which is a join_table of many to one between container and item. Entities in code are mapped using 2 classes: Container and Item.
The relation is unidrectional from Container to Item.
join_table in hibernate is mapped only by annotations in Container class.
#Entity
#Table(name="container")
public class Container {
#Id
#Column(name = "container_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
#JoinTable(name = "item_container",
joinColumns = #JoinColumn(name = "container_id"),
inverseJoinColumns = #JoinColumn(name = "item_id"))
private Set<Item> items;
//getter/setters
}
My problem is: when i have the type of collection Set<Item> items changed to List<Item>, the list contain every Item entity twice. I cant find the reason why, the hashCode and equals methods of Item are based only on the item_id field.
UPDATE:
Code for Item class:
#Entity
#Table(name = "item")
#Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public class Item {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "item_id")
private Long id;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "item_template_id", nullable = false)
private ItemTemplate itemTemplate;
#Column(name = "item_group")
#Enumerated(EnumType.STRING)
private ItemGroup itemGroup;
#Column(name = "amount")
private int amount;
//getter/setters
}
Related
i have three entites named depense ,benifice and categories , when i want to get the benefice_C and the Depenese_C in the category entity .this error displayed to me
“Illegal attempt to map a non collection as a #OneToMany, #ManyToMany or #CollectionOfElements” SpringBoot
Depens Entities
> #Entity
#Getter
#Setter
#Table(name="depense")
public class Depense {
#Id #GeneratedValue
#Column(name = "id_etab")
private Long idEtab;
#ManyToOne
#JoinColumn(name = "personnel_id")
private Personnel personnel;
#ManyToOne
#JoinColumn(name = "CATD")
private Categories categoriesD;
Benfice Entities
> public class Benifice {
#Column(name = "id_etab")
private Long idEtab;
#ManyToOne
#JoinColumn(name = "inscrit_id")
private Inscrit inscrit;
#ManyToOne
#JoinColumn(name = "be_C")
private Categories benificeC;
Categorie entite
> public class Categories implements Serializable {
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idCat;
#OneToMany(mappedBy = "categoriesD", fetch = FetchType.LAZY)
private Depense depense;
#OneToMany(mappedBy = "benificeC", fetch = FetchType.LAZY)
private Benifice benifice;
Your #OneToMany mapping is not correct.
You would need a List/Set/Collection of Objects if you map OneToMany.
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idCat;
#OneToMany(mappedBy = "categoriesD", fetch = FetchType.LAZY)
private List<Depense> depense;
#OneToMany(mappedBy = "benificeC", fetch = FetchType.LAZY)
private List<Benifice> benifice;
I would like to ignore #OnetoMany field in my entity. fetch data need to get actual fields but don't want to fire query to dependent table. But deleting data from parent table needs deletion from dependent table
I have tried #Transient that ignores but the delete is also being ignored. Is there any other option to tell JPA not to fetch data from childs table when i call the parent entity?
#Entity
Table(name = "User")
public class UserEntity implements Serializable {
#Id
#Column(name = "id")
private int id;
#Column(name = "SERIAL", unique = true, nullable = false)
private String serial;
#OneToMany(mappedBy = "serialBySerialId", cascade = CascadeType.ALL)
private Set<UserActionEntity> userActionsById;
}
#Table(name = "user_action")
public class UserActionEntity implements Serializable {
#Id
#Column(name = "id")
private int id;
#Column(name = "action")
private String action;
#ManyToOne
#JoinColumn(name = "USER_ID", referencedColumnName = "ID", nullable = false)
private UserEntity userByUserId;
If you don't want to fire query to dependent table, you can use (fetch = FetchType.LAZY) on UserActionEntity property.
#OneToMany(mappedBy = "serialBySerialId", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UserActionEntity> userActionsById;
I have 4 models:
Blueprint, that describes a single type of Item:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name="name")
private String name;
#ElementCollection
#CollectionTable(name = "BLUEPRINT_TAG", joinColumns = #JoinColumn(name = "blueprint"))
private List<String> tags;
#OneToMany(mappedBy = "blueprint", cascade = CascadeType.ALL, orphanRemoval = true)
private List<BlueprintProperty> properties;
#OneToMany(mappedBy = "blueprint", cascade = CascadeType.ALL, orphanRemoval = true)
#JsonIgnore
private List<Item> items;
#Column(name = "width")
private Float width;
#Column(name = "height")
private Float height;
#Column(name = "imagePath")
private String imagePath;
#Column(name = "zPosition")
private long zPosition;
BlueprintProperty, that describes what information can be entered for each type of Item.
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name = "blueprint")
#JsonIgnore
private Blueprint blueprint;
#Column(name = "name")
private String name;
#Enumerated(EnumType.STRING)
private PropertyType type;
#Column(name = "data")
#Convert(converter = JpaJsonConverter.class)
private ObjectNode data;
#OneToMany(mappedBy = "property", cascade = CascadeType.ALL, orphanRemoval = true)
#JsonIgnore
private List<ItemProperty> itemProperties;
Then there's Item:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name = "parent")
//#Nullable
private Item parent;
#Column(name = "pos_x")
private Float posX;
#Column(name = "pos_y")
private Float posY;
#Column(name = "transformation")
private String transformation;
#ManyToOne
#JoinColumn(name = "blueprint")
private Blueprint blueprint;
#OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
#JsonIgnore
private List<Item> children;
#OneToMany(mappedBy = "item", cascade = CascadeType.ALL, orphanRemoval = true)
private List<ItemProperty> properties;
And finally, ItemProperty, that holds foreign keys referencing Item the specific property belongs to, and BlueprintProperty it's describing:
#Id
#ManyToOne
#JoinColumn(name = "item")
#JsonIgnore
private Item item;
#Id
#ManyToOne
#JoinColumn(name = "property")
#JsonIgnore
private BlueprintProperty property;
#Column(name = "value")
private String value;
Now, I'm not exactly happy with this setup, but that's what I have to work with and unless completely necessary I shouldn't change anything. What I'm trying to do is create a Query that takes a number of Item properties and returns all Items which properties match the query.
Using Query by example sounded promising, but I found out that only SingularAttribute properties can currently be used for property matching.. So that killed that approach, and I don't think I can use native query, because a certain Item can have N properties, and you should be able to enter a query that searches by a single property, up to N properties.
Can someone suggest a way to perform the search I need and get a List of Items matching whose properties matched those entered as a result?
I'm having a problem to map a relationship between instances of one single entity. Let me give you the JPA entities first.
Article entity
#Entity
#Table(name = "article")
public class Article {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "article", orphanRemoval = true)
private Collection<Keyword> keywords;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "article1", orphanRemoval = true)
private Collection<RelatedArticles> relatedArticles;
#Column(name = "content", nullable = false)
#Lob
private String content;
...
}
RelatedArticle entity
#Entity
#Table(name = "related_articles")
public class RelatedArticles {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#JoinColumn(name = "article1_id")
#ManyToOne(optional = false)
private Article article1;
#JoinColumn(name = "article2_id")
#ManyToOne(optional = false)
private Article article2;
private Float weightedJaccardIndex;
...
}
Further explanation
An article can be related to other articles which is realized by the RelatedArticle entity. The article can be referenced by article1 or article2. That means the collection relatedArticles in Article should contain all instances of RelatedArticle where the ID either matches article1 or article2.
Question
How can I map a single collection of RelatedArticles in my Article entity where the origin Article is either article1 or article2?
Alternative solutions are welcome!
Is it possible to expose a manytomany relationship that uses a join entity (that contains extra data columns), below is my entities;
I'm trying to get 'purchases' to show in REST, I've put in 'products' as an example of a working REST mapping;
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, targetEntity = Purchase.class, orphanRemoval = true)
#JoinColumn(name = "user_id", updatable = false)
private List<Purchase> purchases = new ArrayList<>();
#ManyToMany
#JoinColumn(name = "user_id", updatable = false)
private List<Product> products = new ArrayList<>();
}
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
}
#Entity
public class Purchase implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
#ManyToOne
#JoinColumn(name = "user_id", referencedColumnName = "id")
private User user;
#ManyToOne(targetEntity = Prodect.class)
#JoinColumn(name = "product_id", referencedColumnName = "id")
private Product product;
#Column(name = "purchase_date")
private Date purchaseDate;
}
So if i send the REST call;
[GET http://localhost:8080/webapp/users/1]
It returns links for [http://localhost:8080/webapp/users/1/products] but not for [http://localhost:8080/webapp/users/1/purchases]
worked out what the issue was; I need to create a JpaRepository for the Purchase entity. Soon as I added that, the REST links for purchases are available.