I got an object that inherit from another and i am trying to save (persist) it in my db. The problem is that when i try, i got this error :
javax.persistence.PersistenceException:
org.hibernate.exception.SQLGrammarException: could not extract ResultSet
I don't know what i did wrong.. Here is my classes :
#Entity
#Table(name = "calamar.derogation")
public class Derogation
{
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "derogation_seq_gen")
#SequenceGenerator(name = "derogation_seq_gen", sequenceName = "calamar.derogation_id_seq",initialValue = 1, allocationSize = 1)
private int id;
#OneToMany(mappedBy="derogation", cascade = CascadeType.ALL, orphanRemoval=true, fetch = FetchType.EAGER)
#OrderBy("id")
private Set<DerogationFille> listDerogationFille;
[...]
}
#Entity
public abstract class DerogationFille{
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
protected int id;
#ManyToOne
protected Derogation derogation;
[...]
}
#Entity
#Table(name = "calamar.derogationlinux")
public class DerogationLinux extends DerogationFille
{
private String chemin;
private String userFam;
private String serveur;
#Column(name="typederogation")
private String type;
[...]
}
I got the error on this lines :
entityManager.getTransaction().begin();
entityManager.persist(derogation);
EDIT 1 ##
I haven't looked at my correctly, i've got this error into it too, i think it is the main problem
ERROR: relation "hibernate_sequence" does not exist
Please annotate your entities like this
#Table(name = "derogation", schema = "calamar")
Related
I have a class:
#Getter
#Setter
#Entity(name = "car")
public class CarEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", nullable = false)
private UUID id;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "car")
private List<WheelEntity> wheels;
private String number;
}
And a query finding an entity by one of its parameters and fetching nested collection:
#Query("SELECT c FROM car c WHERE c.number=:loanContract")
Optional<CarEntity> findByNumber(#Param("number") String number);
Everything works fine in runtime, but when I try to test it, the nested collection in the entity read from database is always null. I'm using Junit5 and H2 in-memory database.
I try to save object Run to database. I defined relation between Run and City. One city could have many runs. I got problem with city_id. Is null.
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
java.sql.SQLIntegrityConstraintViolationException: Column 'city_id' cannot be null
My entieties and controller:
City
#Entity
#Getter
#Setter
#Builder
#NoArgsConstructor
#AllArgsConstructor
#Table(name = "cities")
public class City {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "city_id")
private long id;
#OneToMany(mappedBy = "city", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Run> runs = new ArrayList<>();
private String name;
}
Run
#Entity
#Builder
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Table(name = "runs")
public class Run {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "name_run")
private String nameRun;
#Column(name = "distance")
private double distance;
#Column(name = "date")
private Date date;
#Column(name = "my_time")
private String myTime;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "city_id", nullable = false)
#OnDelete(action = OnDeleteAction.CASCADE)
#JsonIgnore
private City city;
}
Controller
#CrossOrigin
#RestController
#RequestMapping("/api/")
public class RunController {
private RunRepository runRepository;
private RunService runService;
public RunController(RunRepository runRepository, RunService runService) {
this.runRepository = runRepository;
this.runService = runService;
}
#GetMapping("runs")
public ResponseEntity<List<Run>> getRuns() {
return runService.getRuns();
}
#PostMapping("runs")
public ResponseEntity addRun(#RequestBody Run run) {
return new ResponseEntity<>(runRepository.save(run), HttpStatus.OK);
}
}
I would like to save the run in DB.
My test request looks like :
{
"nameRun": "test",
"distance":"5.0",
"date":"2020-12-12",
"myTime":"50:40",
"city":"test1"
}
Result from evaluate expresion in Intelijj:
Why the City = null? Is here error in mapping?
Can you try with this json but you need to pass city id in json.
{
"nameRun": "test",
"distance": "5.0",
"date": "2020-12-12",
"myTime": "50:40",
"city": {
"id": 1,
"name": "test1"
}
}
Thanks
First of all, use Long for id please. It is better to add #Entity annotation too.
#Entity
public class City {
#Id
#GeneratedValue
private Long id;
#OneToMany(mappedBy = "city", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Run> runs = new ArrayList<>();
}
#Entity
public class Run {
#Id
#GeneratedValue
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
private City city;
}
You need to set city_id when you save Run.
The simplest way to do that is just create a fake transient City and set id to it.
City city = new City();
city.setId(1L);
Run run = new Run();
run.setCity(city);
repository.save(run);
Obviously you should have a city with id 1L in the database.
Other options are
Use something like session.load() Hibernate analogue with Spring repository to create City without loading it from datatbase.
Load City entity entirely by id.
if you wanna save any run class,
Run run = new Run();
City city = new City();
city.getRuns().add(run);
runRepository.save(run);
if you wanna save any run class, first you need to insert to (Arraylist) runs variable of city class like city.getRuns().add(run) after filling run then you can runRepository.save(run).
Also my samples are here. You can look at myclasses.
First class is called Patient .
#Data
#AllArgsConstructor
#NoArgsConstructor
#Entity
#ToString
#Table(name = "aapatient")
public class Patient {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AA_PATIENT_SEQ")
#SequenceGenerator(sequenceName = "AA_PATIENT_SEQ", allocationSize = 1, name = "AA_PATIENT_SEQ")
#Column(name = "patientid")
private Long patientid;
private String name;
private String lastname;
#OneToMany(mappedBy = "patient", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Problem> problems;
}
Second Class called Problem is this one.
#Data
#AllArgsConstructor
#NoArgsConstructor
#ToString
#Entity
#Table(name="aaproblem")
public class Problem{
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AA_PATIENT_SEQ")
#SequenceGenerator(sequenceName = "AA_PATIENT_SEQ", allocationSize = 1, name = "AA_PATIENT_SEQ")
#Column(name = "problemid")
private Long problemid;
private String problemName;
private String problemDetail;
#Temporal(TemporalType.TIMESTAMP)
Date creationDate;
#NotNull
#ManyToOne(optional = true, fetch = FetchType.LAZY)
#JoinColumn(name = "patient_id")
private Patient patient;
}
although true entity naming i get mappedBy reference an unknown target entity property
regarding to this and this the solution for mappedby exception is to naming the entity correctly i did that but i still getting the exception
#Entity
#Table(name = "CONTEST")
public class Contest extends eg.com.etisalat.base.entity.BaseEntity implements
Serializable {
private static final long serialVersionUID = 1L;
#Id
#SequenceGenerator(name = "CONTEST_ID_GENERATOR", sequenceName = "SEQ_CONTEST_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CONTEST_ID_GENERATOR")
#Column(name = "ID")
private long contestId;
#OneToMany(cascade = { CascadeType.REMOVE, CascadeType.REFRESH }
,mappedBy="contest")
private List<Challenge> challenges;
//attributes
//getters &setters
}
and this is the ohter entity which has a many to one relation with contest entity
#Id
#SequenceGenerator(name = "CHALLENGE_ID_GENERATOR", sequenceName = "SEQ_Challenge_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CHALLENGE_ID_GENERATOR")
#Column(name = "CHALLENGE_ID")
private long Id;
#ManyToOne(targetEntity=Contest.class)
#JoinColumn(name = "CONTEST_ID")
private Contest conestId;
//attributes
//getters &setters
}
thanks in advance
In Challenge entity, the field should be private Contest contest; with a matching getter and setter - getContest() and setContest().
I'm trying to create a social app service. I have user with confirmed or nonconfirmed relationships.
When I load UserA, the result look like belove.
"result":{
"idUser":"UserA",
"unconFriendships":[
{
"idUser":"UserB",
"unconFriendships":[
{
"idUser":"UserC",
"unconFriendships":[
...
While it has to be look like
"result":{
"idUser":"UserA",
"unconFriendships":[
{
"idUser":"UserB",
"unconFriendships":null //only one level have to fetched
....
I thought that this was because jackson json library, I debbuged the code. Before serialization, I inspected userA object and I saw that userA.unconFriendships.userB.unconFriendships was not null and with size bigger than 0.
Nearly it has been 12 hours, still couldn't solve the problem. Please help me to solve this. Thanks in advence.
Here is UserEntity.java
#Entity
#Table(name="aduser",uniqueConstraints=#UniqueConstraint(columnNames = {"idUser","nmEmail"}))
#JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="cdUser")
public class UserEntity extends BaseEntity {
protected static final long serialVersionUID = 8864033727886664353L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "admin_seq")
#SequenceGenerator(name = "admin_seq", sequenceName = "CDUSER_SEQUENCE", allocationSize = 1)
#Column(name="cdUser")
private long cdUser;
#OneToMany(mappedBy = "owner", targetEntity=Friendship.class)
#JsonProperty
protected Set<UnconfirmedFriendship> unconFriendships;
#OneToMany(mappedBy = "owner", targetEntity=Friendship.class)
#JsonProperty
protected Set<UnconfirmedFriendship> conFriendships;
...
Friendship.java
#Entity
#Table(name="aduserfriend")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "verified")
#JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="friend_cduser",scope=UserEntity.class)
public abstract class Friendship extends BaseEntity{
protected static final long serialVersionUID = -670863816551430192L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "cdFriendship")
private long cdFriendship;
#ManyToOne
#JsonIgnore
#JoinColumn(name = "owner_cduser")
protected UserEntity owner;
#ManyToOne
#JoinColumn(name = "friend_cduser")
protected UserEntity friend;
#Column(name = "verified",insertable=false,updatable=false)
private boolean verified;
...
UnconfirmedFriendship.java and ConfirmedFriendship.java
#Entity
#DiscriminatorValue(value = "0")//this value is 1 for Confirmed relationship
public class UnconfirmedFriendship extends Friendship {
private static final long serialVersionUID = 57796452166904132L;
}
I have the following situation:
#Entity
class A{
#Id
#SequenceGenerator(name = "SEQ_AID", sequenceName = "SEQ_AID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_AID")
private Long aId;
#OneToOne(fetch=FecthType.LAZY,optional=false,cascade=CascadeType.ALL)
private B b;
...
}
#Entity
class B{
#Id
private A a;
...
}
In other words: There is a OneToOne association between A and B. B is a weak entity, and its Id is derived from class A.
I've already tested some solutions as adding #PrimaryKeyJoinColumn under #OneToOne as this article mentions. But I got this error: "org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): B"
I don't know if it's relevant in this case, but I'm using Oracle 11g.
UPDATED
I think I'm in the right way. Here is the actual state of my problem:
#Entity
class A{
#Id
#SequenceGenerator(name = "SEQ_AID", sequenceName = "SEQ_AID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_AID")
private Long aId;
#OneToOne(fetch=FecthType.LAZY,optional=false,cascade=CascadeType.ALL)
#PrimaryKeyJoinColumn(name="aId")
private B b;
...
}
#Entity
class B{
#Id
#OneToOne
#JoinColumn(name="aId)
private A a;
...
}
The error now is a bit different:
java.sql.SQLException: ORA-00904: "B"."A": invalid identifier
It is trying to find the column A (instead of AID) in the table B. I don't know how to specify that the column name is B.AID and not B.A.
I solved my problem following this link
The correct answer would be:
#Entity
public class A {
#Id
#GeneratedValue
#Column(name = "aId")
private Long id;
#OneToOne(fetch = FetchType.LAZY, optional=false, cascade = CascadeType.ALL, mappedBy = "a")
private B b;
...
}
#Entity
#org.hibernate.annotations.GenericGenerator(name="a-primarykey", strategy="foreign", parameters={#org.hibernate.annotations.Parameter(name="property", value="a")})
public class B {
#Id
#GeneratedValue(generator = "a-primarykey")
#Column(name = "aId")
private Long id;
#OneToOne
#PrimaryKeyJoinColumn
private A a;
...
}
Have you tried this on Entity B?
#Entity class B {
#Id #OneToOne
#JoinColumn(name = "table_a_id") //put the correct column name for A's pk here
private A a;
....
}