I'm trying to implement an internationalization class to translate contents from database.
I have these tables:
And I have theses classes:
ProductModel:
public class ProductModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idproduct_model")
private Integer idproductModel;
#Size(max = 80, message = "El campo nombre esta vacio")
#Column(name = "name")
private String name;
#Size(max = 45, message = "El campo referencia esta vacio")
#Column(name = "productSuppReference")
private String productSuppReference;
...
Language:
public class LanguageCountry implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Column(name = "id_language")
private Integer idLanguage;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 45)
#Column(name = "description")
private String description;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "languageCountry1")
private List<ProductModelI18n> productModelI18nList;
...
ProductModelI18n:
public class ProductModelI18n implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected ProductModelI18nPK productModelI18nPK;
#Size(max = 80)
#Column(name = "name")
private String name;
#Lob
#Size(max = 2147483647)
#Column(name = "description")
private String description;
#Size(max = 800)
#Column(name = "description2")
private String description2;
#JoinColumn(name = "language_country", referencedColumnName = "id_language", insertable = false, updatable = false)
#ManyToOne(optional = false)
private LanguageCountry languageCountry1;
ProductModelI18nPK:
#Embeddable
public class ProductModelI18nPK implements Serializable {
#Basic(optional = false)
#NotNull
#Column(name = "product_model")
private int productModel;
#Basic(optional = false)
#NotNull
#Column(name = "language_country")
private int languageCountry;
I have problems because I need a double PK in a ProductModelI18n table to get a manytomany relation between productmodel and languageCountry and now I don't know how to do a join table in productModel.
I need an ArrayList/Map in ProductModel class.
Thank you in advance!
Jose
EDIT:
Sorry my bad I missed the fact that you have extra columns in the Join table, so just need to decompose the ManyToMany association between ProductModel and LanguageCountry into two OneToMany associations.
Your code should look like:
in ProductModel class:
#OneToMany
private List<ProductModelI18n> ProductLanguages;
In LanguageCountry class:
#OneToMany
private List<ProductModelI18n> ProductLanguages;
And in your ProductModelI18n class:
Keep all the other fields including the IdPK and add the following declarations.
#ManyToOne
#PrimaryKeyJoinColumn(name="productModel", referencedColumnName="idproductModel")
private ProductModel productModels ;
#ManyToOne
#PrimaryKeyJoinColumn(name="languageCountry", referencedColumnName="idLanguage")
private LanguageCountry LanguageCountries;
Note:
Make sure you include all the getters and setters.
There's no need to create the class ProductModelI18n to make a ManyToMany relation between productmodel and languageCountry.
You only need two Collections in these two classes mapped with #ManyToMany annotation where in one of the two sides you define a #JoinTable here's the code you need:
In ProductModel class:
#ManyToMany
#JoinTable(
name="ProductModelI18n",
joinColumns={#JoinColumn(name="productModel", referencedColumnName="idproductModel")},
inverseJoinColumns={#JoinColumn(name="languageCountry", referencedColumnName="idLanguage")})
private List<LanguageCountry> languageCountries;
And in your LanguageCountry class:
#ManyToMany(mappedBy="languageCountries")
private List<ProductModel> productModels;
And you will get a Join table between the two tables as represented in the picture.
For further information you can take a look at:
JPA 2 Tutorial – Relationships – Many To Many.
Java Persistence/ManyToMany
Related
i am tryning to join two entities where typDossAmo can have a list of DossMedic
but i get the following error:
Entity class [class ma.cnss.wstest.TypDossAmo] must use a #JoinColumn instead of #Column to map its relationship attribute [drugs].
public class TypDossAmo implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "ID")
private BigInteger id;
#Id
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 9)
#Column(name = "NUM_DOSS")
private String numDoss;
#Column(name = "p_tab_medic")
#OneToMany(mappedBy="doss")
private List<DossMedic> drugs;........
public class DossMedic implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected DossMedicPK dossMedicPK;
#Column(name = "ID")
private BigInteger id;
#Column(name = "NOMBRE")
private BigInteger nombre;
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="NUM_DOSS")
private TypDossAmo doss;
The idea of the annotation #Column is for common columns without any relationship with other tables, when you use #JoinColumn is to say to the ORM that two tables have a relationship and the way to join them is with this column.
In this case the solution is change the annotation #Column by #JoinColumn in TypDossAmo
public class TypDossAmo {
#JoinColumn(name = "p_tab_medic")
#OneToMany(mappedBy="doss")
private List<DossMedic> drugs;
}
I have two classes and I want to have a one to many relation between them, for e.g.:
Home(id<int>, rooms<string>)
Vehicle(id<int>, home_id<int>, name<string>)
I need to have a relation between Home and Vehicle class using Home.id and vehicle.home_id.
Please suggest any example which I can use here for CURD operation to implement REST service.
I need to have a relation between Home and Vehicle class using Home.id
and vehicle.home_id.
Your entities should look like this :
Vehicle Entity
#Entity
#Table(name = "vehicle", catalog = "bd_name", schema = "schema_name")
#XmlRootElement
public class Vehicle implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Column(name = "name")
private String name;
#JoinColumn(name = "home_id", referencedColumnName = "id")
#ManyToOne
private Home homeId;
//constructor getter & setters
}
Home Entity
#Entity
#Table(name = "home", catalog = "bd_name", schema = "schema_name")
#XmlRootElement
public class Home implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Column(name = "room")
private Character room;
#OneToMany(mappedBy = "homeId")
private List<Vehicle> vehicleList;
//constructor getter & setters
}
I'm having two entities Car and CarDescription where CarDescription is depending on another foreign key from the table Language.
What I' trying to accomplish is to have a HashMap in Car such that whenever I'm having a Car entity-object I am able to access all descriptions from the language id.
Entity Car.java
#Entity
#Table(name = "Car")
public class Car extends AbstractTimestampEntity implements Serializable {
private static final long serialVersionUID = -5041816842632017838L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "ID", unique = true, nullable = false)
private Long id;
#OneToMany(mappedBy="car")
#MapKeyColumn(name = "language_ID")
// #MapKey(name = "language") // does not work either
private Map<Long, CarDescription> carDescription = new HashMap<>(0);
}
Entity CarDescription.java
#Entity
#Table( name="car_description",
uniqueConstraints = {
#UniqueConstraint(columnNames={"language_id", "name"})
}
)
public class CarDescription extends AbstractTimestampEntity implements Serializable {
private static final long serialVersionUID = 2840651722666001938L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "ID", unique = true, nullable = false)
private Long id;
#NotNull
#ManyToOne
private Car car;
#NotNull
#OneToOne
private Language language;
// ..
}
Entity Language.java
#Entity
public class Language implements Serializable {
private static final long serialVersionUID = 3968717758435500381L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="ID")
private Long id;
// ..
}
The problem I am having is that the mapping gives me a map from each CarDescription.id to CarDescription.
How can I accomplish a correct mapping?
In CarDescription you need to add the languageId property:
#Column(name = "language_id", insertable = false, updatable = false)
private Long languageId;
#NotNull
#OneToOne
#JoinColumn(name = "language_id")
private Language language;
public void setLanguage(Language language) {
this.languageId = language.getId();
this.language = language;
}
Then you can use it in the Car entity like this:
#OneToMany(mappedBy="car")
#MapKey(name = "languageId")
private Map<Long, CarDescription> carDescription = new HashMap<>(0);
I have a many-to-many relationship which looks like this:
The primary key is combination of three columns and I'm using eclipselink. I created these classes to be able to insert in the join-table :
#Entity
#Table(name = "definition_property")
#NamedQueries({
#NamedQuery(name = "DefinitionProperty.findAll", query = "SELECT d FROM DefinitionProperty d")})
public class DefinitionProperty extends AbstractEntity{
private static final long serialVersionUID = 1L;
#EmbeddedId
protected DefinitionPropertyPK pk;
#JoinColumn(name = "dtid", referencedColumnName = "id", insertable = false, updatable = false)
#ManyToOne(optional = false)
private DefinitionType definitionType;
#JoinColumn(name = "prid", referencedColumnName = "id", insertable = false, updatable = false)
#ManyToOne(optional = false)
private Property property;
#Column(name = "initial_value")
#Basic(optional = false)
private String initialValue;
// setters and getters
}
And PK class:
#Embeddable
public class DefinitionPropertyPK implements Serializable{
#Column(name = "dtid")
private Integer idDt;
#Column(name = "prid")
private Integer idProperty;
#Column(name = "initial_value")
private String initialValue;
//hashcode, equals, setters and getters
}
Entitiy 1:
#Entity
#Table(name = "definition_type")
public class DefinitionType extends AbstractEntity implements EntityItem<Integer> {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer idDT;
#Size(max = 45)
#Column(name = "name")
private String dtName;
#Size(max = 45)
#Column(name = "description")
private String description;
#OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "definitionType")
private List<DefinitionProperty> definitionProperties = new ArrayList<DefinitionProperty>();
}
Entity 2:
#Entity
#Table(name = "property")
public class Property extends AbstractEntity implements EntityItem<Integer>{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE)
#Basic(optional = false )
#Column(name = "id")
private Integer idProperty;
#Column(name = "name")
#Size(max = 45)
private String propertyName;
#Enumerated(EnumType.STRING)
#Column(name = "type")
private Type fieldType;
#Column(name = "init_value")
#Size(max = 45)
private String initialValue;
#OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "property")
private List<DefinitionProperty> definitionPeoperties= new ArrayList<DefinitionProperty>();
}
Exception : I get this exception when trying to persist a new DefinitionType:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.microsoft.sqlserver.jdbc.SQLServerException: The column name 'initial_value' is specified more than once in the SET clause. A column cannot be assigned more than one value in the same SET clause. Modify the SET clause to make sure that a column is updated only once. If the SET clause updates columns of a view, then the column name 'initial_value' may appear twice in the view definition.
Error Code: 264
Call: INSERT INTO definition_property (initial_value, initial_value, dtid, prid) VALUES (?, ?, ?, ?)
bind => [4 parameters bound]
Question : Why there are two initial_values in the set clause and where am I wrong in my code?
Ref: How do you Set Up a Many-to-Many Relationship with Junction Table using JPA/EclipseLink
Ref: JPA simple many-to-many with eclipselink
Ref: https://giannigar.wordpress.com/2009/09/04/mapping-a-many-to-many-join-table-with-extra-column-using-jpa/
I'm trying a web project using JPA and JSF-primefaces.
I have a bug with insert/update an object which has #ManyToOne relationship.
after inserting, #JoinColumn is blank field. (sorry ican't post image, this is image link)
after insert
and then, after reload list, blank field is back to normal
after reload
I'm using unidirectional #ManyToOne entity
Place.java
#Entity
#Table(name = "place")
#XmlRootElement
public class Place implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
...
#Basic(optional = false)
#NotNull
#Column(name = "prefecture_id")
private int prefectureId;
#ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "prefecture_id",referencedColumnName = "id", updatable = false,insertable = false)
private Aken prefecture;
Aken.java
#Entity
#Table(name = "aken")
#XmlRootElement
public class Aken implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Column(name = "id")
private Short id;
#Size(max = 50)
#Column(name = "data")
private String data;
method update to database
#Stateless
#TransactionManagement(TransactionManagementType.BEAN)
public class PlaceFacade extends AbstractFacade<Place> {
#PersistenceContext(unitName = "JutenPU")
private EntityManager em;
#Resource
private UserTransaction userTransaction;
public void edit(Place place){
try{
getUserTransaction().begin();
getEntityManager().merge(place);
getUserTransaction().commit();
}catch(Exception e){
System.out.println(e.getMessage());
}
}
method retrieve data on table
public List<Place> findAll() {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(Place.class));
return getEntityManager().createQuery(cq).getResultList();
}
I'm using JAVA EE7, glassfish server 4, primefaces 4.0
Thanks for your help
#JoinColumn(name = "prefecture_id",referencedColumnName = "id", updatable = false,insertable = false)
you marked Place foreign key column READONLY.
remove limitations: #JoinColumn(name = "prefecture_id",referencedColumnName = "id")