Я работаю над проектом начальной загрузки с модулем Hibernate ORM, использующим MySQL в качестве базы данных.
Существует база данных college_students
, которая содержит таблицу student
, и эта таблица содержит следующие поля:
CREATE TABLE student(
_id INTEGER(11) NOT NULL,
student_name VARCHAR(50) NOT NULL,
attend_lecture INTEGER(11) NOT NULL,
iso_dom INTEGER(11) NOT NULL,
iso_dow INTEGER(11) NOT NULL,
iso_month INTEGER(11) NOT NULL,
iso_year INTEGER(11) NOT NULL,
iso_week INTEGER(11) NOT NULL,
updated_on BIGINT(20) NOT NULL,
PRIMARY KEY (_id, updated_on)
);
В этом проекте есть ученический класс.Ученический класс - это класс модели в моем проекте
@Entity
@Table(name="student")
@NamedQuery(name="Student.findAll", query="SELECT s FROM Student s")
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private StudentPK id;
@Column(name="student_name")
private String studentName;
@Column(name="attend_lecture")
private String attendLecture;
@Column(name="iso_dom")
private String isoDom;
@Column(name="iso_dow")
private String isoDow;
@Column(name="iso_month")
private String isMonth;
@Column(name="updated_on")
private String updatedOn;
}
Ученический класс StudentPK - это
@Embeddable
public class StudentPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
@Column(name="_id")
private int Id;
@Column(name="updated_on")
private String updatedOn;
public StudentPK() {
}
public StudentPK(int Id, String updatedOn) {
super();
this.Id = Id;
this.updatedOn = updatedOn;
}
public int getId() {
return this.Id;
}
public void setId(int Id) {
this.Id = Id;
}
public String getUpdatedOn() {
return this.updatedOn;
}
public void setUpdatedOn(String updatedOn) {
this.updatedOn = updatedOn;
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof StudentPK)) {
return false;
}
StudentPK castOther = (StudentPK)other;
return
(this.Id == castOther.Id)
&& this.updatedOn.equals(castOther.updatedOn);
}
public int hashCode() {
final int prime = 31;
int hash = 17;
hash = hash * prime + this.Id;
hash = hash * prime + this.updatedOn.hashCode();
return hash;
}
}
Ученический класс StudentService запрашивает обращение к базе данных Mysql с помощью StudentRepository, которая расширяется с помощью CrudRepository
@Service
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class StudentService {
private static final Logger logger =LoggerFactory.getLogger(StudentService.class);
@Autowired
StudentRepository studentRepository;
@PersistenceContext
private EntityManager entityManager;
public Student insertIntoStudentTable(String name, int attendLecture, int isoDom, int isoDow, int isMonth) {
// insert into Student table
BigInteger currentTime = BigInteger.valueOf(new Date().getTime());
Student student = new Student();
student = StudentMapper.registerStudent(student, name,
new StudentPK(Constants.INSERT_ID_DEFAULT_VALUE, currentTime.toString()), attendLecture,
Constants.INSERT_RECORD_TYPE_DEFAULT_VALUE, isoDom, isoDow, isMonth);
student = studentRepository.save(student);
logger.debug("detach stduent");
String updatedOn = student.getId().getUpdatedOn();
logger.debug("updated on : " + updatedOn);
entityManager.detach(student);
student = studentRepository.findByUpdatedOnAndNewRecordType(updatedOn);
logger.debug("after detach and query");
logger.debug("student id : " + student.getId()); // getting error at this point null pointer error
return student;
}
}
NOTE:
Для таблицы учеников применяется триггер, который увеличивает значение Student.id в таблице.Например:
_id | student_name | attend_lecture |iso_dom | iso_dow | iso_month| iso_year | iso_week | updated_on
1 | Rahul | 15 | 2 | 1 | 1 | 2019 | 1 | 2588899955
Таким образом, таблица ученика, имеющая 1 запись и значение поля _id, назначается триггером.
Trigger
delimiter |
CREATE TRIGGER Student_bit BEFORE INSERT ON Student
FOR EACH ROW
BEGIN
SET @_id = NULL;
IF NEW._id = 0 THEN
SELECT COALESCE(MAX(_id) + 1, 1) INTO @_id FROM student;
SET NEW._id = @_id;
END IF;
END;
|
delimiter ;
Здесь исходный кодработает отлично.Изменение триггера: значение поля _id от 0 до 1 или какое (максимальное число + 1)
Но после применения триггера в объекте класса Student не сохраняется никаких данных для этой проблемы. Мне нужно применить запрос, чтобы получить данные избазы данных.
Становится хуже, когда я применил аннотацию @Transactional к классу StudentService.java.
Error:
2019-05-31 18:15:08.899 DEBUG 6972 --- [nio-8080-exec-4] com.test.student.service.Test2Service : after detach and query
2019-05-31 18:15:08.906 ERROR 6972 --- [nio-8080-exec-4] c.t.s.r.GlobalExceptionHandler : Error message- null
2019-05-31 18:15:08.906 ERROR 6972 --- [nio-8080-exec-4] c.t.s.r.GlobalExceptionHandler : Error message string- java.lang.NullPointerException
2019-05-31 18:15:08.907 INFO 6972 --- [nio-8080-exec-4] c.t.s.r.GlobalExceptionHandler : ERROR response JSON- {"type":"Error","status":"fail","status_code":0,"user_message":"Internal Server Error! Please contact Administrator"}
Questions:
Не удается сохранить данные после применения триггера к таблице базы данных?
Есть ли возможное решение для аннотации @Transaction, используемой в классе обслуживания?
Ошибка возникает после добавления аннотации @Trasactional ккласс обслуживания.