When I try save instance, I get this strange error:
WARN [15:06:27,917] JDBCExceptionReporter - SQL Error: 20000, SQLState: 42X04
ERROR[15:06:27,917] JDBCExceptionReporter - Column 'ad0b8d24-f596-47cb-9d79-06a3c9c1de26' is either not in any table in the FROM list or appears within a join specification and is outside the scope of the join specification or appears in a HAVING clause and is not in the GROUP BY list. If this is a CREATE or ALTER TABLE statement then 'ad0b8d24-f596-47cb-9d79-06a3c9c1de26' is not a column in the target table.
Row is not inserted into database.
It looks like it is trying to use scenario_id (uuid) as column name. But why?
I am using this Data Access Object:
public interface ScenarioDao extends GenericDao<Scenario, String> {
public List<Scenario> getScenariosWhereOwner(Person owner);
public List<Scenario> getScenariosWhereOwner(Person person, int LIMIT);
...
}
public interface GenericDao <T, PK extends Serializable>{
public PK create(T newInstance) {
PK primaryKey = (PK) getHibernateTemplate().save(newInstance);
return primaryKey;
}
}
POJO:
#Entity
#Table(name = "SCENARIO")
#XmlRootElement
public class Scenario implements Serializable, Comparable<Scenario> {
private static final long serialVersionUID = -6608175331606366993L;
private String scenarioId;
private Person person;
private ResearchGroup researchGroup;
private String title;
private int scenarioLength;
private boolean privateScenario;
private String description;
private String scenarioName;
private String mimetype;
private Set<History> histories = new HashSet<History>(0);
private Set<Experiment> experiments = new HashSet<Experiment>(0);
private boolean userMemberOfGroup;
private Blob scenarioFile;
private String group;
private Boolean availableFile;
private InputStream fileContentStream;
#Transient
public boolean isUserMemberOfGroup() {
return userMemberOfGroup;
}
public void setUserMemberOfGroup(boolean userMemberOfGroup) {
this.userMemberOfGroup = userMemberOfGroup;
}
#Transient
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
#Transient
public Boolean getAvailableFile() {
return availableFile;
}
public void setAvailableFile(Boolean availableFile) {
this.availableFile = availableFile;
}
public Scenario() {
}
public Scenario(Person person, ResearchGroup researchGroup) {
this.person = person;
this.researchGroup = researchGroup;
}
public Scenario(Person person, ResearchGroup researchGroup, String title,
int scenarioLength, boolean privateScenario, String description,
String scenarioName, String mimetype, Set<History> histories,
Set<Experiment> experiments) {
this.person = person;
this.researchGroup = researchGroup;
this.title = title;
this.scenarioLength = scenarioLength;
this.privateScenario = privateScenario;
this.description = description;
this.scenarioName = scenarioName;
this.mimetype = mimetype;
this.histories = histories;
this.experiments = experiments;
}
#Id
#GeneratedValue(generator = "system-uuid")
#GenericGenerator(name = "system-uuid", strategy = "uuid2")
#Column(name = "SCENARIO_ID", nullable = false, length = 36, scale = 0)
public String getScenarioId() {
return this.scenarioId;
}
public void setScenarioId(String scenarioId) {
this.scenarioId = scenarioId;
}
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "OWNER_ID", nullable = false)
public Person getPerson() {
return this.person;
}
public void setPerson(Person person) {
this.person = person;
}
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "RESEARCH_GROUP_ID", nullable = false)
public ResearchGroup getResearchGroup() {
return this.researchGroup;
}
public void setResearchGroup(ResearchGroup researchGroup) {
this.researchGroup = researchGroup;
}
#Column(name = "TITLE", unique = true)
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
#Column(name = "SCENARIO_LENGTH", precision = 22, scale = 0)
public int getScenarioLength() {
return this.scenarioLength;
}
public void setScenarioLength(int scenarioLength) {
this.scenarioLength = scenarioLength;
}
#Column(name = "PRIVATE", precision = 1, scale = 0)
public boolean isPrivateScenario() {
return this.privateScenario;
}
public void setPrivateScenario(boolean privateScenario) {
this.privateScenario = privateScenario;
}
#Lob
#Type(type = "org.hibernate.type.TextType")
#Column(name = "DESCRIPTION")
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
#Column(name = "SCENARIO_NAME")
public String getScenarioName() {
return this.scenarioName;
}
public void setScenarioName(String scenarioName) {
this.scenarioName = scenarioName;
}
#Column(name = "MIMETYPE")
public String getMimetype() {
return this.mimetype;
}
public void setMimetype(String mimetype) {
this.mimetype = mimetype;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "scenario")
public Set<History> getHistories() {
return this.histories;
}
public void setHistories(Set<History> histories) {
this.histories = histories;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "scenario")
public Set<Experiment> getExperiments() {
return this.experiments;
}
public void setExperiments(Set<Experiment> experiments) {
this.experiments = experiments;
}
#XmlJavaTypeAdapter(BlobSerializer.class)
#Basic(fetch = FetchType.LAZY)
#Lob
#Column(name = "SCENARIO_FILE", nullable = true)
public Blob getScenarioFile() {
return this.scenarioFile;
}
public void setScenarioFile(Blob scenarioFile) {
this.scenarioFile = scenarioFile;
}
#Override
public int compareTo(Scenario scen) {
return this.title.compareTo(scen.getTitle());
}
public void setFileContentStream(InputStream inputStream) {
this.fileContentStream = inputStream;
}
#Transient
public InputStream getFileContentStream() {
return fileContentStream;
}
}
I try to create it using this code:
scenario = new Scenario();
scenario.setPrivateScenario(some boolean);
scenario.setScenarioLength(some int);
scenario.setDescription(some string);
scenario.setTitle(some string);
scenario.setResearchGroup(some ResearchGroup);
scenario.setPerson(some Person);
All these parameters are set correctly. I am also using GenericDao with other objects without errors. Here is insert statement generated by hibernate:
DEBUG[16:07:25,132] SQL - insert into SCENARIO (DESCRIPTION, MIMETYPE, OWNER_ID, PRIVATE, RESEARCH_GROUP_ID, SCENARIO_FILE, SCENARIO_LENGTH, SCENARIO_NAME, TITLE, SCENARIO_ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
TRACE[16:07:25,153] BasicBinder - binding parameter [1] as [LONGVARCHAR] - newscenariodescription
TRACE[16:07:25,153] BasicBinder - binding parameter [2] as [VARCHAR] - <null>
TRACE[16:07:25,153] BasicBinder - binding parameter [3] as [VARCHAR] - 9e87924e-3a14-4f82-ad57-c191ead873b5
TRACE[16:07:25,153] BasicBinder - binding parameter [4] as [BIT] - false
TRACE[16:07:25,154] BasicBinder - binding parameter [5] as [VARCHAR] - b399f04f-92a7-427c-9af5-f90055cb1ddc
TRACE[16:07:25,154] BasicBinder - binding parameter [6] as [BLOB] - <null>
TRACE[16:07:25,154] BasicBinder - binding parameter [7] as [INTEGER] - 5
TRACE[16:07:25,154] BasicBinder - binding parameter [8] as [VARCHAR] - <null>
TRACE[16:07:25,154] BasicBinder - binding parameter [9] as [VARCHAR] - newscenario
TRACE[16:07:25,154] BasicBinder - binding parameter [10] as [VARCHAR] - 2d71bcd2-756e-4ffd-82b0-9649d7f05e0b
WARN [16:07:25,180] JDBCExceptionReporter - SQL Error: 20000, SQLState: 38000
ERROR[16:07:25,180] JDBCExceptionReporter - The exception 'java.sql.SQLException: Column '2d71bcd2-756e-4ffd-82b0-9649d7f05e0b' is either not in any table in the FROM list or appears within a join specification and is outside the scope of the join specification or appears in a HAVING clause and is not in the GROUP BY list. If this is a CREATE or ALTER TABLE statement then '2d71bcd2-756e-4ffd-82b0-9649d7f05e0b' is not a column in the target table.' was thrown while evaluating an expression.
When I try execute:
String query = "insert into SCENARIO (DESCRIPTION, MIMETYPE, OWNER_ID, PRIVATE, RESEARCH_GROUP_ID, FILE_CONTENT, SCENARIO_LENGTH, SCENARIO_NAME, TITLE, SCENARIO_ID) values ('newscenariodescription', NULL, '9e87924e-3a14-4f82-ad57-c191ead873b5', 0, 'b399f04f-92a7-427c-9af5-f90055cb1ddc', NULL, 5, NULL, 'text', '2d71bcd2-756e-4ffd-82b0-9649d7f205e0b')";
session.createSQLQuery(query).executeUpdate();
I get same error.
When I try execute query directly I get very strange error:
SQL Error [20000] [38000]: The exception 'java.lang.NoClassDefFoundError: org/jumpmind/symmetric/db/derby/DerbyFunctions' was thrown while evaluating an expression.
SQL Error [XJ001]: Java exception: 'org/jumpmind/symmetric/db/derby/DerbyFunctions: java.lang.NoClassDefFoundError'.
The exception 'java.lang.NoClassDefFoundError: org/jumpmind/symmetric/db/derby/DerbyFunctions' was thrown while evaluating an expression.
The exception 'java.lang.NoClassDefFoundError: org/jumpmind/symmetric/db/derby/DerbyFunctions' was thrown while evaluating an expression.
Java exception: 'org/jumpmind/symmetric/db/derby/DerbyFunctions: java.lang.NoClassDefFoundError'.
org/jumpmind/symmetric/db/derby/DerbyFunctions
I forget to set capture_big_lobs in trigger table. Changing value to 1 solved problem. However if the column is NULL, then SymmetricDS will throw Null Pointer Exception. I am using 3.5.10, so maybe it's solved in newer versions.
Related
I am trying to use the JPA Criteria API to filter the results and aggregate them using simple count, min, avg and max. I am using Spring Boot 2.7.8, so I am trying to use Interface-projections such that these aggregated results look the same as the simpler queries done automatically by the Spring repositories.
My domain entity (simplified for brevity) looks like this:
#Entity
#Table(name = "vehicle_stopped")
#IdClass(VehicleStopped.VehicleStoppedPK.class)
public class VehicleStopped implements Serializable {
#Id
#Column(name = "stopped_session_uuid", nullable = false)
private String stoppedSessionUuid;
#Id
#Column(name = "start_ts", nullable = false)
private OffsetDateTime startTs;
#Column(name = "end_ts", nullable = false)
private OffsetDateTime endTs;
#Column(name = "duration_seconds")
private Double durationSeconds;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "zone_id")
private CameraZone cameraZone;
#Override
public VehicleStoppedPK getId() {
VehicleStopped.VehicleStoppedPK pk = new VehicleStopped.VehicleStoppedPK();
pk.setStartTs(this.getStartTs());
pk.setStoppedSessionUuid(this.getStoppedSessionUuid());
return pk;
}
public OffsetDateTime getEndTs() {
return endTs;
}
public void setEndTs(OffsetDateTime endTs) {
this.endTs = endTs;
}
public Double getDurationSeconds() {
return durationSeconds;
}
public void setDurationSeconds(Double durationSeconds) {
this.durationSeconds = durationSeconds;
}
public CameraZone getCameraZone() {
return cameraZone;
}
public void setCameraZone(CameraZone cameraZone) {
this.cameraZone = cameraZone;
}
public VehicleType getVehicleType() {
return vehicleType;
}
public void setVehicleType(VehicleType vehicleType) {
this.vehicleType = vehicleType;
}
public String getStoppedSessionUuid() {
return stoppedSessionUuid;
}
public void setStoppedSessionUuid(String stoppedSessionUuid) {
this.stoppedSessionUuid = stoppedSessionUuid;
}
//some details removed for brevity
#Override
public static class VehicleStoppedPK implements Serializable {
private OffsetDateTime startTs;
private String stoppedSessionUuid;
public VehicleStoppedPK() {
}
public OffsetDateTime getStartTs() {
return startTs;
}
public void setStartTs(OffsetDateTime startTs) {
this.startTs = startTs;
}
public String getStoppedSessionUuid() {
return stoppedSessionUuid;
}
public void setStoppedSessionUuid(String stoppedSessionUuid) {
this.stoppedSessionUuid = stoppedSessionUuid;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
VehicleStoppedPK that = (VehicleStoppedPK) o;
return Objects.equals(startTs, that.startTs) && Objects.equals(stoppedSessionUuid, that.stoppedSessionUuid);
}
#Override
public int hashCode() {
return Objects.hash(startTs, stoppedSessionUuid);
}
#Override
public String toString() {
return "VehicleStoppedPK{" +
"startTs=" + startTs +
", stoppedSessionUuid='" + stoppedSessionUuid + '\'' +
'}';
}
}
}
#Entity
#Table(name = "camera_zone")
public class CameraZone implements Serializable {
#Id
#SequenceGenerator(name = "camera_zone_id_seq", sequenceName = "camera_zone_id_seq", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "camera_zone_id_seq")
#Column(name = "id", updatable=false)
private Integer id;
#Column(name = "uuid", unique = true)
private String uuid;
#Column(name = "type")
private String type;
#Column(name = "name")
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CameraZone that = (CameraZone) o;
return Objects.equals(id, that.id) && Objects.equals(uuid, that.uuid) && Objects.equals(camera, that.camera) && Objects.equals(type, that.type) && Objects.equals(name, that.name);
}
#Override
public int hashCode() {
return Objects.hash(id, uuid, camera, type, name);
}
}
The code that I have in my Repository implementation looks like this:
public class SpecificationVehicleStoppedRepositoryImpl
implements SpecificationVehicleStoppedRepository {
#Autowired private EntityManager em;
#Autowired ProjectionFactory projectionFactory;
#Override
public List<VehicleStoppedAggregate> getStoppedVehiclesCount(Specification<VehicleStopped> spec) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Tuple> query = builder.createTupleQuery();
Root<VehicleStopped> root = query.from(VehicleStopped.class);
Predicate predicate = spec.toPredicate(root, query, builder);
if (predicate != null) {
query.where(predicate);
}
Path<Number> duration = root.get("durationSeconds");
Path<CameraZone> zone = root.get("cameraZone");
query
.multiselect(zone,
builder.count(root).alias("totalVehicles"),
builder.min(duration).alias("minDuration"),
builder.avg(duration).alias("avgDuration"),
builder.max(duration).alias("maxDuration"))
.groupBy(zone);
List<Tuple> rawResultList = em.createQuery(query).getResultList();
return project(rawResultList, VehicleStoppedAggregate.class);
}
private <P> List<P> project(List<Tuple> results, Class<P> projectionClass) {
return results.stream()
.map(tuple -> {
Map<String, Object> mappedResult = new HashMap<>(tuple.getElements().size());
for (TupleElement<?> element : tuple.getElements()) {
String name = element.getAlias();
mappedResult.put(name, tuple.get(name));
}
return projectionFactory.createProjection(projectionClass, mappedResult);
})
.collect(Collectors.toList());
}
}
The interface-based projection I am trying to populate (using SpelAwareProxyProjectionFactory) is this:
public interface VehicleStoppedAggregate {
CameraZone getCameraZone();
Integer getTotalVehicles();
Double getMinDuration();
Double getAvgDuration();
Double getMaxDuration();
}
The call to getStoppedVehiclesCount() fails with the following error:
ERROR: column "camerazone1_.id" must appear in the GROUP BY clause or be used in an aggregate function
This error is coming from the PostgreSQL database, and rightly so because the SQL hibernate generates is incorrect:
select
vehiclesto0_.zone_id as col_0_0_,
count(*) as col_1_0_,
min(vehiclesto0_.duration_seconds) as col_2_0_,
avg(vehiclesto0_.duration_seconds) as col_3_0_,
max(vehiclesto0_.duration_seconds) as col_4_0_,
camerazone1_.id as id1_2_,
camerazone1_.name as name2_2_,
camerazone1_.type as type3_2_,
camerazone1_.uuid as uuid4_2_
from
vehicle_stopped vehiclesto0_
inner join
camera_zone camerazone1_
on vehiclesto0_.zone_id=camerazone1_.id cross
where
vehiclesto0_.start_ts>=?
and vehiclesto0_.start_ts<=?
and 1=1
and 1=1
and 1=1
group by
vehiclesto0_.zone_id
It is not grouping by the other fields it is requesting from the joined table.
If I had to use a normal class, instead of a Tuple, it would work, but it would mean I would have to create a class with a huge constructor for all fields for Hibernate to populate it.
Somehow, when I use Interface-based projections with Spring's repositories rather than my criteriaquery, the same scenario works. They manage to populate the one-to-many relationships just fine.
Is there a way to fix this and make Hibernate ask for the right fields?
I am using Hibernate 5.6.14.Final (as bundled with Spring Boot 2.7.8).
I believe the "solution" is two create two "independent" query roots and join them together:
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Tuple> query = builder.createTupleQuery();
Root<VehicleStopped> root = query.from(VehicleStopped.class);
// instead of Path<CameraZone> zone = root.get("cameraZone")
Root<CameraZone> zone = query.from(CameraZone.class);
query.where(builder.equal(zone, root.get("cameraZone")));
Path<Number> duration = root.get("durationSeconds");
query
.multiselect(zone,
builder.count(root).alias("totalVehicles"),
builder.min(duration).alias("minDuration"),
builder.avg(duration).alias("avgDuration"),
builder.max(duration).alias("maxDuration"))
.groupBy(zone);
session.createQuery(query).getResultList();
In that case Hibernate 5 produces following SQL (which actually looks weird from my perspective due to missing columns in group by clause):
select
naturalidc1_.id as col_0_0_,
count(*) as col_1_0_,
min(naturalidc0_.duration_seconds) as col_2_0_,
avg(naturalidc0_.duration_seconds) as col_3_0_,
max(naturalidc0_.duration_seconds) as col_4_0_,
naturalidc1_.id as id1_0_,
naturalidc1_.name as name2_0_,
naturalidc1_.type as type3_0_,
naturalidc1_.uuid as uuid4_0_
from
vehicle_stopped naturalidc0_ cross
join
camera_zone naturalidc1_
where
naturalidc1_.id=naturalidc0_.zone_id
group by
naturalidc1_.id
FYI. Your initial query does work in Hibernate 6 and produced SQL does look more correct but still weird:
select
c1_0.id,
c1_0.name,
c1_0.type,
c1_0.uuid,
count(*),
min(v1_0.duration_seconds),
avg(v1_0.duration_seconds),
max(v1_0.duration_seconds)
from
vehicle_stopped v1_0
join
camera_zone c1_0
on c1_0.id=v1_0.zone_id
group by
1,
2,
3,
4
I am new to hibernate and Data JPA. I try to do an insert into my table but the hibernate query has some columns in it that not exist in my table so it will throw an error. Actually at first when I run my code the hibernate add these extra columns to my table and then I change spring.jpa.hibernate.ddl-auto value to none in application.properties, but now when I delete those extra columns from my table and try to insert a new record I see those columns are in insert method.
My Entity classes
#Entity
public class Content {
#Id
#NotNull
#GeneratedValue
Integer id;
//this can be null if it is a question
#Column(name = "content_id")
Integer content_id;
#NotBlank #NotNull
#Column(name = "body")
String body;
#Column(name = "creationDate")
Timestamp creationDate;
#NotNull
#Column(name = "user_id")
Integer user_id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getContent_id() {
return content_id;
}
public void setContent_id(Integer content_id) {
this.content_id = content_id;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public Timestamp getCreationDate() {
return creationDate;
}
public void setCreationDate(Timestamp creationDate) {
this.creationDate = creationDate;
}
public int getUser_id() {
return user_id;
}
public void setUser_id(Integer user_id) {
this.user_id = user_id;
}
}
my question class extends the content
#Entity
public class Question extends Content {
#NotNull #NotBlank
#Column(name = "subject")
String subject;
#NotNull #NotBlank
#Column(name = "tags")
String tags;
#NotNull
#Column(name = "contentType")
final Integer contentType_id = 1;
#Column(name = "commentCount")
Integer commentCount;
public Question(#Valid #JsonProperty("subject") String subject,
#Valid #JsonProperty("tags") String tags,
#Valid #JsonProperty("body") String body) {
this.subject = subject;
this.tags = tags;
this.body = body;
}
public Integer getContentType_id() {
return contentType_id;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getTags() {
return tags;
}
public void setTags(String tags) {
this.tags = tags;
}
public Integer getCommentCount() {
return commentCount;
}
public void setCommentCount(Integer commentCount) {
this.commentCount = commentCount;
}
}
Service class
#Service
public class QuestionService {
#Autowired
QuestionRepository questionRepository;
public QuestionService(QuestionRepository questionRepository) {
this.questionRepository = questionRepository;
}
public Question postQuestion(Question question){
return questionRepository.save(question);
}
}
Controller
#RequestMapping("easy4lazy/questions")
#RestController
public class QuestionController {
private final QuestionService questionService;
private final int contetnType = 1;
#Autowired
public QuestionController(QuestionService questionService) {
this.questionService = questionService;
}
#PostMapping(path = "/postQuestion" )
public Question postQuestion(#RequestBody Question q){
q.setContent_id(contetnType);
return questionService.postQuestion(q);
}
}
Repository
import com.easy4lazy.proj.model.Question;
import org.springframework.data.repository.CrudRepository;
public interface QuestionRepository extends CrudRepository<Question, Integer> {
}
Error code
Hibernate: insert into content (body, content_id, creation_date, user_id, comment_count, content_type, subject, tags, dtype, id) values (?, ?, ?, ?, ?, ?, ?, ?,'Question', ?)
2019-10-10 18:11:36.513 WARN 11960 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1054, SQLState: 42S22
2019-10-10 18:11:36.515 ERROR 11960 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : Unknown column 'creation_date' in 'field list'
2019-10-10 18:11:36.520 ERROR 11960 --- [nio-8080-exec-3] o.h.i.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [org.hibernate.exception.SQLGrammarException: could not execute statement]
2019-10-10 18:11:36.547 ERROR 11960 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement] with root cause
I don't have content_id, creation_date, comment_count and dtype fields in my table and i don't know why hibernate add them into the query.
is there any way to change the query that hibernate created or fix this problem in any other way, how can I control or manage queries create by hibernate???
I also should mention that I use the postman to send data and check my code.
After lots of searching and working, I found that hibernate naming convention for table columns is in a way that it separate words by an underscore and that was the reason that I saw those columns inside the query generated by hibernate. So if you have a variable inside your class like creationDate hibernate try to converted to creation_date so when I change all my column's name in this method problem solved. Also, the dtype column is a special kind of column that will create by hibernate when many classes use the same table to insert data, it is because to distinguish which class insert the record inside the table and hibernate provide its value with the name of that class.
But you do have content_id and creation_date in your Content entity which the Question entity extends from
I'm having issues trying to delete an entry in my database table.
The structure of the database is as follows:
User ---< UserET >--- ExitTicket
ExitTicket.java
#Entity
#Table(name = "exit_ticket")
public class ExitTicketEntry implements Serializable {
private static final long serialVersionUID = 1L;
private long id;
private String title;
private String dateET;
private Set<UserET> userETs= new HashSet<UserET>();
public ExitTicketEntry() {}
public ExitTicketEntry(String title,String dateET) {
this.title = title;
this.dateET = dateET;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY )
#Column(name = "ticket_id")
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
#OneToMany(mappedBy = "exitTicketEntry", orphanRemoval=true)
public Set<UserET> getUserETs() {
return userETs;
}
public void setUserETs(Set<UserET> userETs) {
this.userETs = userETs;
}
public void addUserETs(UserET userETs) {
this.userETs.add(userETs);
}
//getters and setters
}
UserET.java
#Entity
#Table(name="userET")
public class UserET implements Serializable {
//private static final long serialVersionUID = 1L;
private long answerId;
private User user;
private ExitTicketEntry exitTicketEntry;
private String answer;
private Date dateAnswer;
#Id
#GeneratedValue
#Column(name="answerId")
public long getAnswerId() {
return answerId;
}
public void setAnswerId(long answerId) {
this.answerId = answerId;
}
#ManyToOne(cascade = CascadeType.ALL )
#JoinColumn(name = "user_id")
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "ticket_id")
public ExitTicketEntry getExitTicketEntry() {
return exitTicketEntry;
}
public void setExitTicketEntry(ExitTicketEntry exitTicketEntry) {
this.exitTicketEntry = exitTicketEntry;
}
#Column(name = "answer")
public String getAnswer(){
return answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
#Column(name = "dateAnswer")
#Temporal(TemporalType.DATE)
public Date getDateAnswer() {
return dateAnswer;
}
public void setDateAnswer(Date dateAnswer) {
this.dateAnswer = dateAnswer;
}
User.java
#Entity
#Table(name="USER")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private long id;
private String user_name, user_password, user_type,user_realname;
private Set<UserET> userETs= new HashSet<UserET>();
public User() {
}
public User(String user_name,String user_password,String user_type,String user_realname) {
this.user_name = user_name;
this.user_password = user_password;
this.user_type = user_type;
this.user_realname=user_realname;
}
public void addExitTicketEntry(UserET group) {
this.userETs.add(group);
}
#Id
#GeneratedValue
#Column(name="user_id")
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
#OneToMany(mappedBy = "user", orphanRemoval=true)
public Set<UserET> getUserETs() {
return userETs;
}
public void setUserETs(Set<UserET> userETs) {
this.userETs = userETs;
}
public void addUserETs(UserET userETs) {
this.userETs.add(userETs);
} ... + getters and setters
I am able to insert a new Entry of ExitTicket correctly (using ExitTicketService.java), with this function:
public void addEntryET(ExitTicketEntry exitTicketEntry) {
log.info("adding entry in database");
try {
hibernateTemplate.save(exitTicketEntry);
}
catch(Exception e) {
log.info("error adding an entry in the database->"+e.toString());
}
}
However when I try to delete an entry from the database table, the hibernate delete only does 'select' commands and never gets to do a 'delete'
2018-11-05 09:28:27 INFO AuthService:72 - entro 1 ------
Hibernate: select exitticket0_.ticket_id as ticket_i1_0_0_, exitticket0_.dateET as dateET2_0_0_, exitticket0_.title as title3_0_0_ from exit_ticket exitticket0_ where exitticket0_.ticket_id=?
Mon Nov 05 09:28:27 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
2018-11-05 09:28:27 TRACE BasicBinder:65 - binding parameter [1] as [BIGINT] - [9]
2018-11-05 09:28:27 TRACE BasicExtractor:61 - extracted value ([dateET2_0_0_] : [VARCHAR]) - [2011-05-20]
2018-11-05 09:28:27 TRACE BasicExtractor:61 - extracted value ([title3_0_0_] : [VARCHAR]) - [test1]
2018-11-05 09:28:27 TRACE CollectionType:790 - Created collection wrapper: [com.jcg.spring.hibernate.pojo.ExitTicketEntry.userETs#9]
Hibernate: select userets0_.ticket_id as ticket_i4_2_0_, userets0_.answerId as answerId1_2_0_, userets0_.answerId as answerId1_2_1_, userets0_.answer as answer2_2_1_, userets0_.dateAnswer as dateAnsw3_2_1_, userets0_.ticket_id as ticket_i4_2_1_, userets0_.user_id as user_id5_2_1_, user1_.user_id as user_id1_1_2_, user1_.user_name as user_nam2_1_2_, user1_.user_password as user_pas3_1_2_, user1_.user_realname as user_rea4_1_2_, user1_.user_type as user_typ5_1_2_ from userET userets0_ left outer join USER user1_ on userets0_.user_id=user1_.user_id where userets0_.ticket_id=?
2018-11-05 09:28:27 TRACE BasicBinder:65 - binding parameter [1] as [BIGINT] - [9]
2018-11-05 09:28:27 INFO AuthService:99 - deleted entry with ID#=9
My delete function in my service class:
public void deleteById(Class<?> type, long id) {
log.info("entro 1 ------");
ExitTicketEntry e=(ExitTicketEntry) hibernateTemplate.load(type,id);
hibernateTemplate.delete(e);
}
I've been reading plenty of forums, but still have the same issue, I can't delete any entries. Am I missing something?
getting id = null when I try to insert data in table here is my create table syntax
CREATE TABLE query_builder (
id int(11) NOT NULL AUTO_INCREMENT,
query_title varchar(150) NOT NULL,
sql_query text NOT NULL,
condition varchar(50) NOT NULL,
output_fields varchar(45) NOT NULL,
physician int(11) NOT NULL,
creation_time timestamp NULL DEFAULT CURRENT_TIMESTAMP,
modification_time timestamp NULL DEFAULT NULL,
discription text NOT NULL,
PRIMARY KEY (id),
KEY query_builder_physician_FK_idx (physician),
CONSTRAINT query_builder_physician_FK FOREIGN KEY (physician) REFERENCES physician (Physician_Id) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
and entity for this is
import java.io.Serializable;
import javax.xml.bind.annotation.XmlTransient;
public class QueryBuilder implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false, unique = true)
private Integer id;
#Basic(optional = false)
#Column(name = "query_title")
private String queryTitle;
#Basic(optional = false)
#Lob
#Column(name = "sql_query")
private String sqlQuery;
#Basic(optional = false)
#Column(name = "condition")
private String condition;
#Basic(optional = false)
#Column(name = "output_fields")
private String outputFields;
#Column(name = "creation_time")
#Temporal(TemporalType.TIMESTAMP)
private Date creationTime;
#Column(name = "modification_time")
#Temporal(TemporalType.TIMESTAMP)
private Date modificationTime;
#Basic(optional = false)
#Lob
#Column(name = "discription")
private String discription;
#JoinColumn(name = "physician", referencedColumnName = "Physician_Id")
#ManyToOne(optional = false)
private Physician physician;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name= "querybuilderId")
private Collection<QueryBuilderCondition> queryBuilderConditionCollection;
public QueryBuilder() {
}
public QueryBuilder(Integer id) {
this.id = id;
}
public QueryBuilder(Integer id, String queryTitle, String sqlQuery, String condition, String outputFields, String discription) {
this.id = id;
this.queryTitle = queryTitle;
this.sqlQuery = sqlQuery;
this.condition = condition;
this.outputFields = outputFields;
this.discription = discription;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getQueryTitle() {
return queryTitle;
}
public void setQueryTitle(String queryTitle) {
this.queryTitle = queryTitle;
}
public String getSqlQuery() {
return sqlQuery;
}
public void setSqlQuery(String sqlQuery) {
this.sqlQuery = sqlQuery;
}
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
public String getOutputFields() {
return outputFields;
}
public void setOutputFields(String outputFields) {
this.outputFields = outputFields;
}
public Date getCreationTime() {
return creationTime;
}
public void setCreationTime(Date creationTime) {
this.creationTime = creationTime;
}
public Date getModificationTime() {
return modificationTime;
}
public void setModificationTime(Date modificationTime) {
this.modificationTime = modificationTime;
}
public String getDiscription() {
return discription;
}
public void setDiscription(String discription) {
this.discription = discription;
}
public Physician getPhysician() {
return physician;
}
public void setPhysician(Physician physician) {
this.physician = physician;
}
#XmlTransient
public Collection<QueryBuilderCondition> getQueryBuilderConditionCollection() {
return queryBuilderConditionCollection;
}
public void setQueryBuilderConditionCollection(Collection<QueryBuilderCondition> queryBuilderConditionCollection) {
this.queryBuilderConditionCollection = queryBuilderConditionCollection;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof QueryBuilder)) {
return false;
}
QueryBuilder other = (QueryBuilder) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.medikm.entity.QueryBuilder[ id=" + id + " ]";
}
}
to store data in table i uset below code
builder.setCondition(condition);
builder.setCreationTime(new Date());
builder.setDiscription(discription);
builder.setOutputFields(fields);
builder.setPhysician(new PhysicianJpaController().findPhysician(physicianId));
builder.setQueryTitle(title);
builder.setSqlQuery(query);
em.persist(builder);
em.getTransaction().commit();
em.close();
but above code give me an error
this is the error that i got when i try to persist
[EL Warning]: 2016-06-29 14:22:03.749--UnitOfWork(900737)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.0.2.v20100323-r6872): org.eclipse.persistence.exceptions.DatabaseExceptionInternal Exception: om.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'condition, output_fields, discription, creation_time, modification_time, physici' at line 1Error Code: 1064
Call: INSERT INTO query_builder (query_title, sql_query, condition,output_fields, discription, creation_time, modification_time, physician) VALUES (?, ?, ?, ?, ?, ?, ?, ?) bind => [adfdfafad, SELECT c.Case_Id, c.Age FROM case1 c, patient p, episode e, personal_medical_history pmh, reproductive_history rh WHERE( c.Disease_type = 2 AND c.Primary_Diagnosis_Dt <> '2016/06/22' OR c.Clinical_Stage = 'I'
) AND c.Patient_Id = p.Patient_Id AND e.Case_Id = c.Case_Id
AND pmh.Patient_Id = p.Patient_Id AND rh.Patient_Id = p.Patient_Id
GROUP BY c.Case_Id , "OR", ["ca.Age","ca.aortic_node_positive"], adffda, 2016-06-29 14:22:03.724, null, 200]Query: InsertObjectQuery(com.medikm.entity.QueryBuilder[ id=null ])javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.0.2.v20100323-r6872):org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'condition, output_fields, discription, creation_time, modification_time, physici' at line 1
Error Code: 1064Call: INSERT INTO query_builder (query_title, sql_query, condition, output_fields, discription, creation_time, modification_time, physician) VALUES (?, ?, ?, ?, ?, ?, ?, ?) bind => [adfdfafad, SELECT c.Case_Id, c.Age FROM case1 c, patient p, episode e, personal_medical_history pmh, reproductive_history rhWHERE( c.Disease_type = 2 AND c.Primary_Diagnosis_Dt <> '2016/06/22' OR c.Clinical_Stage = 'I' ) AND c.Patient_Id = p.Patient_Id
AND e.Case_Id = c.Case_Id AND pmh.Patient_Id = p.Patient_Id
AND rh.Patient_Id = p.Patient_Id GROUP BY c.Case_Id , "OR", ["ca.Age","ca.aortic_node_positive"], adffda, 2016-06-29 14:22:03.724, null, 200]Query: InsertObjectQuery(com.medikm.entity.QueryBuilder[ id=null ])at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102)at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63)
please let me know if anything wrong done by me please help... Thank you
Identity sequencing uses special IDENTITY columns in the database to allow the database to automatically assign an id to the object when its row is inserted. Identity columns are supported in many databases, such as MySQL, DB2, SQL Server, Sybase and Postgres. Oracle does not support IDENTITY columns but they can be simulated through using sequence objects and triggers.
If you are using Oracle, that might be the reason.
You can change this code
#GeneratedValue(strategy = GenerationType.IDENTITY)
To this
#GeneratedValue(strategy = GenerationType.SEQUENCE)
PhysicianJpaController() might not find a physician with "physicianId",so you might be trying to do this:
builder.setPhysician(null);
while you have also this:
physician int(11) NOT NULL
hey guys thank you so much for your help issue that I found is in my entity as I check I found that condition is reserved keyword in mysql and because of this I got this error
Having this domain class and using hibernate 3.2.6 integrated with JPA under spring 3.2.4
#Entity
public class PriorityDeviceKeyword {
public enum PriorityDeviceKey {
ALL ("ALL", "ALL DEVICES"),
IOS ("IOS", "IOS"),
ANDROID ("ANDROID","ANDROID");
private final String name;
private final String id;
private PriorityDeviceKey(String name, String id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public String getId() {
return id;
}
}
#Id
private Long id;
#Column(name = "key")
private PriorityDeviceKey key;
#ManyToMany
#JoinTable(name = "t_priority_device_set", joinColumns = #JoinColumn(name = "priority_device__id", referencedColumnName = "id"))
private List<PriorityDevice> priorityDevices;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public PriorityDeviceKey getKey() {
return key;
}
public void setKey(PriorityDeviceKey key) {
this.key = key;
}
public List<PriorityDevice> getPriorityDevices() {
return priorityDevices;
}
public void setPriorityDevices(List<PriorityDevice> priorityDevices) {
this.priorityDevices = priorityDevices;
}
}
When executing this query that I have below method in my DAO class that I execute
#Override
#SuppressWarnings("unchecked")
public Set<PriorityDevices> findPriorityAreas(PriorityDevicesKey key) {
String jpql = "from PriorityDevices as pak where pak.key.name = :keyName";
Query query = entityManager.createQuery(jpql);
query.setParameter("keyName", key.getName());
List<PriorityDevices> priorityDevices = query.getResultList();
return new HashSet<PriorityDevices>(priorityDevices);
}
I get this Exception thrown by the application:
2015-01-14 13:14:50,936 ERROR [com.controller.errors.Error500Controller] - Application thrown an exception
java.lang.IllegalArgumentException: org.hibernate.QueryException: could not resolve property: name of: com.domain.PriorityDevicesKeyword [from com.domain.PriorityDevicesKeyword as
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:624)
at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:96)
at sun.reflect.GeneratedMethodAccessor440.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
Think these changes may work for you:
#Column(name = "key")
#Enumerated(EnumType.STRING)
private PriorityAreaKey key;
and
String jpql = "from PriorityAreaKeyword as pak where pak.key = :keyName";
Query query = entityManager.createQuery(jpql);
query.setParameter("keyName", key);
Hibernate stores enums as an oridnal. Or, when the field is annotated with #Enumerated(EnumType.STRING), as a string with the short name of the Enum. When annotated valid names would be {ALL, IOS, ANDROID}. Either way there is only a single field, the properties of the enum itself are not stored, they are constant after all.
If you want to query for an enum value you have to to query for pak.key = :key and use key as the parameter. Hibernate will do the required translation to ordinal or string.