I'm using spring jpa.
I have the following entity:
public class CountryParameter extends Parameter {
#ElementCollection(targetClass = Country.class)
#CollectionTable(name = "Parameter_Countries", joinColumns = #JoinColumn(name = "segmentParameter_id"))
#Column(name = "country")
#Enumerated(EnumType.STRING)
private Set<Country> countries;
Edit: country is en enum.
The collection table has only 2 columns: parameter_id and country, I would like to add more like id.
how can I do this?
Related
I have two entities connected with many-to-many relationship. For example:
#Entity
public class Account {
#Id
private Long id;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(
name = "account_games",
joinColumns = {#JoinColumn(name="account_id")},
inverseJoinColumns = {#JoinColumn(name="game_id")}
)
private Set<Game> games = new HashSet<>();
}
#Entity
public class Game {
#Id
private Long id;
#ManyToMany(mappedBy = "games", fetch = FetchType.LAZY)
List<Account> accounts = new ArrayList<>();
}
So, there is a table account_games(account_id, game_id) in mysql describing entities many-to-many relations.
I don't want to have Game entity anymore. Is there a way to get rid of Game and leave gameId relation only? So, I'd like to have code something like that:
#Entity
public class Account {
#Id
private Long id;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(
name = "account_games",
joinColumns = {#JoinColumn(name="account_id")},
inverseJoinColumns = {#JoinColumn(name="game_id")}
)
private Set<Long> gameIds = new HashSet<>();
}
without making changes in database.
I've tried different configuration on javax.persistance annotations, but none worked
You can use #ElementCollection and #CollectionTable to achieve that.
#Entity
public class Account {
#Id
private Long id;
#ElementCollection(fetch = FetchType.LAZY)
#CollectionTable(name = "account_games", joinColumns = #JoinColumn(name = "account_id"))
#Column(name = "game_id", nullable = false)
private Set<Long> gameIds = new HashSet<>();
}
You may have to change the query on how to filter data using gameId. Element Collection Query
I have category class as list in entity. How can I fill this entity with a native query?
Product.java
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer pid;
private String name;
#ManyToMany
#JoinTable(
name = "product_category ",
joinColumns = #JoinColumn(
name = "pro_id", referencedColumnName = "pid"),
inverseJoinColumns = #JoinColumn(
name = "cat_id", referencedColumnName = "cid"))
private List<Category> Categories;
}
Category.java
public class Category {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long cid;
private String catname;
private String desc;
#ManyToMany(mappedBy = "categories")
private List<User> users;
}
How should I write a query? How can I fill the Categories list
#Query(value = "*****", nativeQuery = true)
List<Product> productList();
Instead of native query you can use hibernate queries like the below to find something useful.
Find all
ProductRepository.findAll();
Hibernate query
#Query(select product from Product product join product.categories categories)
List<Product> getAllProducts();
you can also sort the above queries using Pageable Object.
Could you please elaborate your question. As you can get the collection list if it is mapped just by find all function of Product Repository.
However, if you are looking to insert collection you can use cascade type in Categories field of Product Repository. This will automatically insert the categories entity once you save the Product entity to database by setting categories list in Product entity.
I've faced with an issue, I've declared the bidirectional #ManyToMany relation between my entities, but when I try to perform the select by repository, the #ManyToMany collection is always empty.
There is an example of my entities:
#Data
#EqualsAndHashCode
#Entity
#Table(name = "provider", schema = "debt")
public class ProviderEntity {
#Id
#Column(name = "provider_id")
private String providerId;
#Column(name = "external_provider_id")
private String externalProviderId;
private String description;
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(
name = "provider_supported_driver", schema = "debt",
joinColumns = #JoinColumn(name = "provider_id", foreignKey = #ForeignKey(name = "FK_PSD_TO_P")),
inverseJoinColumns = #JoinColumn(name = "driver_id", foreignKey = #ForeignKey(name = "FK_PSD_TO_D"))
)
private Set<DriverEntity> drivers = new HashSet<>();
}
#Data
#EqualsAndHashCode
#Entity
#Table(name = "driver", schema = "debt")
public class DriverEntity {
#Id
#Column(name = "driver_id")
private String driverId;
#Enumerated(EnumType.STRING)
private DriverType type;
private String description;
#ManyToMany(mappedBy = "drivers")
private Set<ProviderEntity> provider = new HashSet<>();
}
Also, I've enabled the SQL query logs, that hibernate generates, when I run it, the query works well.
I've tried different guides and answers for the same issues, but I've no result with them.
What's the reason for this behavior? Maybe has somebody any ideas?
I've found the reason for this issue and the problem is in the primary keys of my tables, they aren't generated by sequence or some different way, as I understand Hibernate doesn't understand how to map this columns
I have entity Recipe:
public class Recipe extends BaseEntity{
// other fields
#Column(name = "ingredients")
#ManyToMany
#JoinTable(name = "ingredients_recipes",
joinColumns = {#JoinColumn(name = "recipe_id", referencedColumnName = "id")},
inverseJoinColumns = {#JoinColumn(name = "ingredient_id", referencedColumnName = "id")})
private List<Ingredient> ingredients;
Ingredient:
public class Ingredient extends BaseEntity {
private String name;
#Column(name = "recipes")
#ManyToMany(mappedBy = "ingredients", fetch = FetchType.LAZY)
private List<Recipe> recipes;
I need to select all recipes that contain all or less ingredients from a List. I tried
Set<Recipe> findAllByIngredientsIn(List<Ingredient> ingredientList);
but it checks that the recipe has each ingredient individually. If I give only salt in ingredientList, it return recipes with salt and peper(or other ingredients), but I need to get recipes that only have salt. Is there a jpa repository method that I can use, or I need only a custom query?
Is there a jpa repository method that I can use, or I need only a custom query?
No you'll have to come up with your own query and use it in a #Query annotation.
I want to join these 3 Tables.
Here you see my Person Entity
#Entity
#Table(name = "Person", schema = "public")
public class PatientEntity {
#Id
#Column(name = "id")
private Long id;
#Column(name = "lastname")
private String name;
#OneToMany
#JoinTable(name = "person_contact", joinColumns = { #JoinColumn(name = "person_id") }, inverseJoinColumns = { #JoinColumn(referencedColumnName = "id") })
#Column(name = "contact")
private Set<ContactEntity> contacts;
//Getter Setters
And here is my contact entity:
#Entity
#Table(name="contact",schema="public")
public class ContactEntity {
#Id
#Column(name="id")
private Long id;
#Column(name="phone")
private String phone;
//Getter Setters
I just read the Persons from the Table with findById with a Spring JPARepository, but there is no Contact mapped. There is no error during my HTTP request, but instead of a Contact there is null and this error message:
com.sun.jdi.InvocationException occurred invoking method.
The business case is, that every Person can have one or more contact. Is it possible to make it with JPA Annotations or do I need to map it by myself with a JPQL? Or should I create an Entity for the middle table? (person_contact)
The Database is a PostgreSQL Database.
There is this notification too in the Log:
ERROR: column contacts0_.contacts_id does not exist
Perhaps you meant to reference the column "contacts0_.contact_id".
Position: 306
Your #JoinTable has incorrect #JoinColumn specifications and corresponds to the following ddl.
create table person_contact (person_id bigint not null, contacts_id bigint not null, primary key (person_id, contacts_id))
To map your db structure, use following (note removed #Column annotation)
#OneToMany
#JoinTable(name = "person_contact", joinColumns =
{
#JoinColumn(name = "person_id", referencedColumnName = "id"),
},
inverseJoinColumns = {
#JoinColumn(name = "contact_id", referencedColumnName = "id")
})
private Set<ContactEntity> contacts;
I also encourage you to read https://vladmihalcea.com/the-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate/ and reconsider a db structure without a join table (depending on your load and the effort to make this db change)