JPA releations between OneToMany And ManyToOne - java

I'm new to JPA and trying to do relations between two tables like this:
This is the main class object XParserLinks:
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "link_id")
private Integer linkId;
#OneToMany(mappedBy = "xParserLink", targetEntity = XLinksMedia.class, cascade = CascadeType.ALL)
private List<XLinksMedia> fotos;
...
This is the object class XLinksMedia
public class XLinksMedia implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected XLinksMediaPK xLinksMediaPK;
#ManyToOne #JoinColumn(name = "link_id")
private XParserLinks xParserLink;
and XLinksMediaPK
#Embeddable
public class XLinksMediaPK implements Serializable {
#Basic(optional = false)
#Column(name = "link_id", insertable = false, updatable = false)
private int linkId;
#Basic(optional = false)
#Column(name = "image")
private String image;
Are these relations correct? Because when I want to add new XLinksMedia objects in fotos list, I get LinkId = 0, but I know that LinkId is not 0, I know that LinkId variable have a value.
Here's how I try to set fotos variable in XParseLinks class (preke: is XParseLinks object witch have his primary key LinkId):
XLinksMedia foto = new XLinksMedia();
foto.setXLinksMediaPK(new XLinksMediaPK());
foto.setxParserLink(preke);
foto.getXLinksMediaPK().setImage(e.attr("src"));
preke.getFotos().add(foto);

Even I don't know what is your expectation, When I test your coding, it is OK. I just put some of the OverLoad Constructor for easy data initialization in your classes. But, you use GenerationType.IDENTITY, that's why I set auto increate column for link_id of XParserLinks. The main of the following coding is same as yours.
Your point Here's how I try to set fotos variable in XParseLinks class (preke: is XParseLinks object witch have his primary key LinkId):. Check Test.java
XParserLinks.java
#Entity
public class XParserLinks implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "link_id")
private Integer linkId;
#OneToMany(mappedBy = "xParserLink", targetEntity = XLinksMedia.class, cascade = CascadeType.ALL)
private List<XLinksMedia> fotos;
private String something;
public XParserLinks() {
fotos = new ArrayList<XLinksMedia>();
}
public XParserLinks(String something) {
this.something = something;
fotos = new ArrayList<XLinksMedia>();
}
//getter and setter
}
XLinksMediaPK.java
#Embeddable
public class XLinksMediaPK implements Serializable {
#Basic(optional = false)
#Column(name = "link_id", insertable = false, updatable = false)
private int linkId;
#Basic(optional = false)
#Column(name = "image")
private String image;
public XLinksMediaPK(){
}
public XLinksMediaPK(int linkId, String image) {
this.linkId = linkId;
this.image = image;
}
//getter and setter
}
XParserLinks.java
#Entity
public class XParserLinks implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "link_id")
private Integer linkId;
#OneToMany(mappedBy = "xParserLink", targetEntity = XLinksMedia.class, cascade = CascadeType.ALL)
private List<XLinksMedia> fotos;
private String something;
public XParserLinks() {
fotos = new ArrayList<XLinksMedia>();
}
public XParserLinks(String something) {
this.something = something;
fotos = new ArrayList<XLinksMedia>();
}
//getter and setter
public void add(XLinksMedia media) {
fotos.add(media);
}
}
Test.java
public class Test {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPA");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
XParserLinks xParserLink = new XParserLinks("something");
XLinksMediaPK pk1 = new XLinksMediaPK(0, "image_1");
XLinksMediaPK pk2 = new XLinksMediaPK(0, "image_2");
XLinksMediaPK pk3 = new XLinksMediaPK(0, "image_3");
xParserLink.add(new XLinksMedia(pk1, xParserLink));
xParserLink.add(new XLinksMedia(pk2, xParserLink));
xParserLink.add(new XLinksMedia(pk3, xParserLink));
em.persist(xParserLink);
System.out.println("Success...");
em.getTransaction().commit();
em.close();
}
}

Related

Spring Data/JPA and errorType : object references an unsaved transient instance - save the transient instance before flushing

I have this error with JPA when I update a Person with my repository appUserRepository.save():
" 2022-07-16 10:27:30.080 ERROR 4792 --- [nio-7777-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; WeightRecord; nested exception is java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.quentingenet.openweighttracker.entity.WeightRecord] with root cause
"
I've looked at posts on stackoverflow regarding this error but can't find any solutions. I also tried the cascadeType.ALL. Just bellow you can see in Class 'WeightRecordController' the post method 'saveWeight'. The 'personRepository.save(personToUpdate);' create error when it's called.
#Entity
#Table(name = "person")
public class Person implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="id_person")
private Long idPerson;
#ElementCollection
private List<WeightRecord> userPersonnalWeightsRecord = new ArrayList<WeightRecord>();
#OneToOne( cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "id_initial_data")
private InitialData userInitData;
#OneToOne( cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "id_user")
private AppUser appUserPerson;
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "id_weight_record")
private WeightRecord weightRecord;
#Entity
#Table(name = "weight_record")
public class WeightRecord implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_weight_record")
private Long idWeightRecord;
#Column(name = "weight_record_date", nullable = true)
private LocalDate weightRecordDate;
#Min(1)
#Max(635)
#Column(name = "weight_kg_record", nullable = true, precision = 1)
private Double weightKgRecord;
#Min(1)
#Max(99)
#Column(name = "percent_fat_mass", nullable = true, precision = 1)
private Double percentFatMass;
#Min(1)
#Max(99)
#Column(name = "percent_muscular_mass", nullable = true, precision = 1)
private Double percentMuscularMass;
#Min(1)
#Max(99)
#Column(name = "percent_body_water", nullable = true, precision = 1)
private Double percentBodyWater;
#Min(1)
#Max(99)
#Column(name = "percent_bone_mass", nullable = true, precision = 1)
private Double percentBoneMass;
#Table(name = "initial_data")
#Entity
public class InitialData implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_initial_data")
private Long idInitialData;
#Min(5)
#Max(636)
#Column(name = "goal_weight", nullable = true, precision = 1)
private Double goalWeight;
#Min(25)
#Max(300)
#Column(name = "body_size", nullable = true)
private Integer bodySize;
// #Size(min = 3, max = 5, message = "Please choose between MAN or WOMAN")
#Column(name = "sex", nullable = true)
private String sex;
#Min(1917)
#Max(2022)
#Column(name = "year_birth", nullable = true)
private Integer yearBirth;
#Entity
#Table(name = "app_users")
public class AppUser implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_user")
private Long idUser;
#NotEmpty
#Size(min = 3, max = 36)
#Column(name = "appUsername", nullable = false, unique = true)
private String appUsername;
#NotEmpty
#Size(min = 4, max = 255)
#Column(name = "password", nullable = false)
private String password;
#RestController
#RequestMapping("/weights")
public class WeightRecordController {
#Autowired
WeightRecordServiceImpl weightRecordServiceImpl;
#Autowired
WeightRecordRepository weightRecordRepository;
#Autowired
AppUserRepository appUserRepository;
#Autowired
PersonRepository personRepository;
private final Logger logger = LoggerFactory.getLogger(WeightRecordController.class);
public Long getAppUserConnectedId(Principal principal) {
// TODO user/principal is null... so exception is raise with message "User not
// found"
if (!(principal instanceof UsernamePasswordAuthenticationToken)) {
throw new RuntimeException(("User not found"));
}
logger.info("USER IS PRESENT IN DATABASE FROM FUNCTION 'getAppUserConnectedId()'");
UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) principal;
AppUser appUserFinded = appUserRepository.findByAppUsername(token.getName());
return appUserFinded.getIdUser();
}
// TODO
#PostMapping
public ResponseEntity<WeightRecord> saveWeight(#RequestBody WeightRecord weightRecord, Principal principal) {
logger.info("POST /weights");
Long appUserConnectedId = this.getAppUserConnectedId(principal);
Optional<Person> personUserToSave = personRepository.findById(appUserConnectedId);
logger.info("PERSON FINDED IN DATABASE");
if (personUserToSave.isPresent()) {
logger.info("USER IS PRESENT IN DATABASE FROM saveWeightController");
weightRecordServiceImpl.saveWeightRecord(weightRecord);
logger.info("WEIGHT RECORD IS SAVED NOW");
} else {
return new ResponseEntity<WeightRecord>(HttpStatus.BAD_REQUEST);
}
Person personToUpdate = personRepository.findById(appUserConnectedId).orElseThrow();
List<WeightRecord> personWeightsList = personToUpdate.getUserPersonnalWeightsRecord();
personWeightsList.add(weightRecord);
personToUpdate.setUserPersonnalWeightsRecord(personWeightsList);
logger.info("WEIGHT UPDATED IN PERSONNAL USER LIST WITH ID n°{}",appUserConnectedId);
//TODO : FIX PROBLEM just bellow
personRepository.save(personToUpdate);
logger.info("PERSON WITH ID N°{} IS UPDATED NOW.", personToUpdate.getIdPerson());
return new ResponseEntity<WeightRecord>(weightRecord, HttpStatus.CREATED);
}
#Repository
public interface PersonRepository extends JpaRepository<Person, Long> {
}
In fact the problem concerned entities mapping. Instead of #ElementCollection i use now #OneToMany for the user's weights list and it's ok.
I have imported a screenshoot of my Entities after this change. Thanks for help !
Just bellow my new entity Person :
#Entity
#Table(name = "person")
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_person")
private Long idPerson;
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "id_initial_data")
private InitialData userInitData;
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "id_user")
private AppUser appUserPerson;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<WeightRecord> weightsList;
/*Getters and setters*/

Mysql - JPA no insert into thrid table Many to Many

I have Many-To-Many relation in my project, i can write in my two Entities table, the relational table does not get anything written.
EspecificacionEscenario Class:
public class EspecificacionEscenario implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idespecificacionEscenario")
private Integer idespecificacionEscenario;
#Column(name = "codigo")
private String codigo;
#Column(name = "fecha")
#Temporal(TemporalType.TIMESTAMP)
private Date fecha;
#Column(name = "nombreProceso")
private String nombreProceso;
#Column(name = "nombreEscenario")
private String nombreEscenario;
#Column(name = "objetivoEscenario")
private String objetivoEscenario;
#Column(name = "lugarEscenario")
private String lugarEscenario;
#Column(name = "recursoEscenario")
private String recursoEscenario;
#Column(name = "restriccionEscenario")
private String restriccionEscenario;
#Column(name = "actoresEscenario")
private String actoresEscenario;
#ManyToMany(mappedBy = "especificacionEscenarioList", fetch = FetchType.LAZY)
private List<Elicitacion> elicitacionList;
#ManyToMany(mappedBy = "especificacionEscenarioList", fetch = FetchType.LAZY)
private List<Episodio> episodioList;
#ManyToMany(mappedBy = "especificacionEscenarioList", fetch = FetchType.LAZY)
private List<Educcion> educcionList;
Episodio class:
public class Episodio implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idepisodio")
private Integer idepisodio;
#Column(name = "codigo")
private String codigo;
#Column(name = "objetivoEpisodio")
private String objetivoEpisodio;
#Column(name = "descripcionEpisodio")
private String descripcionEpisodio;
#Column(name = "recursosEpisodio")
private String recursosEpisodio;
#Column(name = "restriccionEpisodio")
private String restriccionEpisodio;
#Column(name = "actor")
private String actor;
#JoinTable(name = "especificacionEscenarioEpisodio", joinColumns = {
#JoinColumn(name = "idepisodio", referencedColumnName = "idepisodio")}, inverseJoinColumns = {
#JoinColumn(name = "idespecificacionEscenario", referencedColumnName = "idespecificacionEscenario")})
#ManyToMany(fetch = FetchType.LAZY)
private List<EspecificacionEscenario> especificacionEscenarioList;
Main code:
public static void main(String[] args) {
EpisodioDao episodioDao = new EpisodioDao();
EspecificacionEscenarioDao escenarioDao = new EspecificacionEscenarioDao();
Episodio episodio = new Episodio();
episodio.setCodigo("e01");
episodio.setDescripcionEpisodio("descripcion episodio");
EspecificacionEscenario ee = new EspecificacionEscenario();
ee.setCodigo("ee-01");
List<Episodio> listaE = new ArrayList<>();
listaE.add(episodio);
ee.setEpisodioList(listaE);
episodioDao.registrarEpisodio(episodio);
System.exit(0);
}
when doing the persistence in the entities the information is saved automatically, but in the table third table it does not insert the primary keys.
I have added CascadeType.ALL on Episodio as it is the owner of this relation.
Following code may help you. I have tested with spring data jpa.
#Setter
#Getter
#Entity
public class Episodio implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idepisodio")
private Integer idepisodio;
#Column(name = "codigo")
private String codigo;
#Column(name = "objetivoEpisodio")
private String objetivoEpisodio;
#Column(name = "descripcionEpisodio")
private String descripcionEpisodio;
#Column(name = "recursosEpisodio")
private String recursosEpisodio;
#Column(name = "restriccionEpisodio")
private String restriccionEpisodio;
#Column(name = "actor")
private String actor;
#JoinTable(name = "especificacionEscenarioEpisodio",
joinColumns = {
#JoinColumn(name = "idepisodio", referencedColumnName = "idepisodio")},
inverseJoinColumns = {
#JoinColumn(name = "idespecificacionEscenario", referencedColumnName = "idespecificacionEscenario")})
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<EspecificacionEscenario> especificacionEscenarioList;
}
#Setter
#Getter
#Entity
public class EspecificacionEscenario implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idespecificacionEscenario")
private Integer idespecificacionEscenario;
#Column(name = "codigo")
private String codigo;
#Column(name = "fecha")
#Temporal(TemporalType.TIMESTAMP)
private Date fecha;
#Column(name = "nombreProceso")
private String nombreProceso;
#Column(name = "nombreEscenario")
private String nombreEscenario;
#Column(name = "objetivoEscenario")
private String objetivoEscenario;
#Column(name = "lugarEscenario")
private String lugarEscenario;
#Column(name = "recursoEscenario")
private String recursoEscenario;
#Column(name = "restriccionEscenario")
private String restriccionEscenario;
#Column(name = "actoresEscenario")
private String actoresEscenario;
#ManyToMany(mappedBy = "especificacionEscenarioList", fetch = FetchType.LAZY)
private List<Episodio> episodioList;
}
EspecificacionEscenario especificacionEscenario = new EspecificacionEscenario();
especificacionEscenario.setCodigo("ee-01");
List<EspecificacionEscenario> especificacionEscenarios = new ArrayList<>();
especificacionEscenarios.add(especificacionEscenario);
Episodio episodio = new Episodio();
episodio.setCodigo("e01");
episodio.setDescripcionEpisodio("descripcion episodio");
episodio.setEspecificacionEscenarioList(especificacionEscenarios);
episodioRepo.save(episodio);

Saving relation JPA with Spring boot

I'm doing a registration and I have the fields
Nome:
Data de Nascimento:
Inscrição Estadual:
Nome Responsável:
CPF Responsável:
Cep:
Bloco:
Número:
when i saving, I can not write data from the PessoasEnderecos class, the other data is recording normal. I'm getting all the data on the screen so much that I debugged the browser to see ..
It shows no error. Does anyone know what I'm missing ??
my class Pacientes
#Entity
#Table(name = "pacientes", schema = "sau")
public class Pacientes implements Serializable {
private static final long serialVersionUID = 5776384003601026304L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idPaciente")
private Long idPaciente;
#JoinColumn(name="idPessoa")
#ManyToOne(cascade = CascadeType.ALL)
private Pessoas pessoa;
#Column(name = "nomeResponsavel")
private String nomeResponsavel;
#Column(name = "cpfResponsavel")
private String cpfResponsavel;
public Pacientes() {
}
//gets and sets
}
my class Pessoas
#Entity
#Table(name = "pessoas", schema="glb")
public class Pessoas implements Serializable {
private static final long serialVersionUID = -4042023941980758267L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
private Long idPessoa;
#Temporal(TemporalType.DATE)
private Date dataNascimento;
private String inscricaoEstadual;
private String inscricaoMunicipal;
private String nome;
public Pessoas() {
}
//gets and sets
}
#Entity
#Table(name = "pessoas_enderecos" ,schema="glb")
public class PessoasEnderecos implements Serializable {
private static final long serialVersionUID = -2560542418318988673L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idPessoaEndereco;
private String bloco;
private String cep;
private String numero;
#JoinColumn(name="idPessoa")
#ManyToOne(optional = false, cascade = CascadeType.ALL)
private Pessoas pessoa;
public PessoasEnderecos() {
}
//gets and sets
}
my methods
class Controller
#RequestMapping(method = RequestMethod.POST, value = "/pacientes")
public Pacientes cadastrarPacientes(#RequestBody Pacientes pac) {
return pacientesService.cadastrar(pac);
}
class service
public Pacientes cadastrar(Pacientes pacientes){
return pacRepository.save(pacientes);
}
class repository
public interface PacientesRepository extends JpaRepository<Pacientes, Integer> {
}
You should also add the linkage #OneToMany in Pacientes:
public class Pacientes implements Serializable {
...
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "pessoa")
#PrimaryKeyJoinColumn
private List<PessoasEnderecos> pessoasEnderecos = new ArrayList<>();
Update:
and your JSON should be something like this:
{
"nomeResponsavel": "abc",
"pessoasEnderecos": [
{
"bloco": "sdds",
"cep": "sdasdsad",
"numero": "sdasdsa"
}
]
}

Using JPA Criteria API to return all object where a Collection property contains a certain value

I am trying to dynamicaly create a Specification for my Spring-data-jpa project
Here is my specification for the moment:
public class DemandsSpecs implements Specification<SvDem> {
private static final Logger LOG = LogManager.getLogger();
private final DemandsCritera critera;
private final List<Predicate> predicateList;
public DemandsSpecs(final DemandsCritera critera) {
this.critera = critera;
this.predicateList = new ArrayList<>();
}
#Override
public Predicate toPredicate(final Root<SvDem> root,
final CriteriaQuery<?> query,
final CriteriaBuilder cb) {
this.predicateList.add(cb.between(root.get(SvDem_.hdCreation), critera.getBegin(), critera.getEnd()));
if (critera.getSoc() != null) {
LOG.debug("socId {}", critera.getSoc());
this.predicateList.add(cb.equal(root.get(SvDem_.socId), critera.getSoc()));
}
if (critera.getManagementAct() != null) {
LOG.debug("actgesId {}", critera.getManagementAct());
this.predicateList.add(cb.equal(root.get(SvDem_.actgesId), critera.getManagementAct()));
}
if (critera.getStatus() != null) {
LOG.debug("statutId {}", critera.getStatus());
this.predicateList.add(cb.equal(root.get(SvDem_.statutId), critera.getStatus()));
}
if (!StringUtils.isBlank(critera.getId())) {
LOG.debug("id {}", critera.getId());
this.predicateList.add(cb.like(root.get(SvDem_.id), '%' + critera.getId() + '%'));
}
return query.where(cb.and(predicateList.toArray(new Predicate[predicateList.size()])))
.orderBy(cb.desc(root.get("hdCreation")))
.getRestriction();
}
}
The DemandsCritera also have a String property metadata.
public class DemandsCritera implements Serializable {
private static final Long serialVersionUID = 1L;
private Date begin;
private Date end;
private RfActges managementAct;
private String metadata;
private RfStatut status;
private RfSoc soc;
private String id;
/* getters and setters */
}
SvDem has a property svMetaCollection which is a Collection<SvMeta>.
#Entity
#Table(name = "sv_dem")
public class SvDem implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
private String id;
#Basic(optional = false)
#Column(name = "HD_CREATION")
#Temporal(TemporalType.TIMESTAMP)
private Date hdCreation;
#Lob
private String user;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "svDem")
#JsonManagedReference
private Collection<SvMeta> svMetaCollection;
#JoinColumn(name = "ACTGES_ID", referencedColumnName = "ID")
#ManyToOne(optional = false)
private RfActges actgesId;
#JoinColumn(name = "STATUT_ID", referencedColumnName = "ID")
#ManyToOne(optional = false)
private RfStatut statutId;
#JoinColumn(name = "SOC_ID", referencedColumnName = "ID")
#ManyToOne(optional = false)
private RfSoc socId;
/* getters, setters and other irrelevant properties */
}
The SvMeta object has a String property value
#Entity
#Table(name = "sv_meta")
public class SvMeta implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected SvMetaPK svMetaPK;
#Basic(optional = false)
#Lob
private String value;
#JoinColumn(name = "META_ID", referencedColumnName = "ID", insertable = false, updatable = false)
#ManyToOne(optional = false)
private RfMeta rfMeta;
#JoinColumn(name = "DEM_ID", referencedColumnName = "ID", insertable = false, updatable = false)
#ManyToOne(optional = false)
#JsonBackReference
private SvDem svDem;
}
I want to return all the SvDem where any of its SvMeta has a value equals to the DemandsCritera.metadata.
How can I achieve that?
I just needed to add this to my toPredicate method of DemandsSpecs:
if (!StringUtils.isBlank(critera.getMetadata())) {
LOG.debug("metadata {}", critera.getMetadata());
Join<SvDem, SvMeta> metas = root.join(SvDem_.svMetaCollection);
this.predicateList.add(cb.equal(metas.get(SvMeta_.value), critera.getMetadata()));
}

How to avoid creating all fields in child classes with inheritance

I have three entities and i have one parent class. Tarifa entity has "pvp" column, so I don't want it in "servicio" entity. The problem is that jpa force me to create column "pvp" in "servicio" table because i am using inheritance. Is there some way to avoid creating "pvp" column in "servicio" table?
#Entity
#Table(name="tarifa")
#AttributeOverride(name = "nombre", column = #Column(name = "nombre", insertable = false, updatable = false))
public class Tarifa extends Concepto
{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#OneToMany(mappedBy = "tarifa")
private List<Servicio> servicios = new ArrayList<Servicio>();
/*#Column(name="pvp")
private float pvp;*/
#Column(name="descuento")
private float descuento;
#Column(name="fecha_inicio")
private Date fechaInicio;
#Column(name="fecha_fin")
private Date fechaFin;
#Entity
#Table(name="producto")
public class Producto extends Concepto
{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#Column(name="descripcion")
private String descripcion;
#Column(name="stock")
private int stock;
#Column(name="coste")
private float coste;
/*#Column(name="pvp")
private float pvp;*/
#OneToMany(mappedBy="producto")
private List<DetalleFactura> detalleFactura = new ArrayList<DetalleFactura>();
#Entity
#Table(name="servicio")
#AttributeOverride(name = "pvp", column = #Column(name = "pvp", insertable = false, updatable = false))
public class Servicio extends Concepto
{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#ManyToOne(cascade = {CascadeType.ALL})
#JoinColumn(name="id_tarifa")
private Tarifa tarifa;
#ManyToOne(cascade = {CascadeType.ALL})
#JoinColumn(name="id_animal")
private Animal animal;
#OneToOne(mappedBy="servicio", cascade = {CascadeType.ALL})
private CitaServicio citaServicio;
#OneToMany(mappedBy="servicio")
private List<DetalleFactura> detalleFactura = new ArrayList<DetalleFactura>();
#MappedSuperclass
public abstract class Concepto
{
#Column(name="nombre")
private String nombre;
#Column(name="pvp")
private float pvp;

Categories

Resources