The error occurs when I try to get a list from two tables
i.e University and Usermaster, where Usermaster is the parent Table.
I am trying to get data from both tables based on University .
University Entity
package entity;
import java.io.Serializable;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
*
* #author 3gth
*/
#Entity
#Table(name = "university")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "University.findAll", query = "SELECT u FROM University u"),
#NamedQuery(name = "University.findByUniversityUname", query = "SELECT u FROM University u WHERE u.universityUname = :universityUname"),
#NamedQuery(name = "University.findByUniversityRegNo", query = "SELECT u FROM University u WHERE u.universityRegNo = :universityRegNo"),
#NamedQuery(name = "University.findByUniversityWebsite", query = "SELECT u FROM University u WHERE u.universityWebsite = :universityWebsite")})
public class University implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 50)
#Column(name = "universityUname")
private String universityUname;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 10)
#Column(name = "universityRegNo")
private String universityRegNo;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 100)
#Column(name = "universityWebsite")
private String universityWebsite;
#Basic(optional = false)
#NotNull
#Lob
#Size(min = 1, max = 65535)
#Column(name = "universityDesc")
private String universityDesc;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "universityUname")
private List<College> collegeList;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "universityUname")
private List<Student> studentList;
#JoinColumn(name = "universityUname", referencedColumnName = "username", insertable = false, updatable = false)
#OneToOne(optional = false)
private Usermaster usermaster;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "universityUname")
private List<Faculty> facultyList;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "universityUname")
private List<Course> courseList;
public University() {
}
public University(String universityUname) {
this.universityUname = universityUname;
}
public University(String universityUname, String universityRegNo, String universityWebsite, String universityDesc) {
this.universityUname = universityUname;
this.universityRegNo = universityRegNo;
this.universityWebsite = universityWebsite;
this.universityDesc = universityDesc;
}
public String getUniversityUname() {
return universityUname;
}
public void setUniversityUname(String universityUname) {
this.universityUname = universityUname;
}
public String getUniversityRegNo() {
return universityRegNo;
}
public void setUniversityRegNo(String universityRegNo) {
this.universityRegNo = universityRegNo;
}
public String getUniversityWebsite() {
return universityWebsite;
}
public void setUniversityWebsite(String universityWebsite) {
this.universityWebsite = universityWebsite;
}
public String getUniversityDesc() {
return universityDesc;
}
public void setUniversityDesc(String universityDesc) {
this.universityDesc = universityDesc;
}
#XmlTransient
public List<College> getCollegeList() {
return collegeList;
}
public void setCollegeList(List<College> collegeList) {
this.collegeList = collegeList;
}
#XmlTransient
public List<Student> getStudentList() {
return studentList;
}
public void setStudentList(List<Student> studentList) {
this.studentList = studentList;
}
public Usermaster getUsermaster() {
return usermaster;
}
public void setUsermaster(Usermaster usermaster) {
this.usermaster = usermaster;
}
#XmlTransient
public List<Faculty> getFacultyList() {
return facultyList;
}
public void setFacultyList(List<Faculty> facultyList) {
this.facultyList = facultyList;
}
#XmlTransient
public List<Course> getCourseList() {
return courseList;
}
public void setCourseList(List<Course> courseList) {
this.courseList = courseList;
}
#Override
public int hashCode() {
int hash = 0;
hash += (universityUname != null ? universityUname.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 University)) {
return false;
}
University other = (University) object;
if ((this.universityUname == null && other.universityUname != null) || (this.universityUname != null && !this.universityUname.equals(other.universityUname))) {
return false;
}
return true;
}
#Override
public String toString() {
return "entity.University[ universityUname=" + universityUname + " ]";
}
}
Usermaster Entity
package entity;
import java.io.Serializable;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
*
* #author 3gth
*/
#Entity
#Table(name = "usermaster")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Usermaster.findAll", query = "SELECT u FROM Usermaster u"),
#NamedQuery(name = "Usermaster.findByUsername", query = "SELECT u FROM Usermaster u WHERE u.username = :username"),
#NamedQuery(name = "Usermaster.findByPassword", query = "SELECT u FROM Usermaster u WHERE u.password = :password"),
#NamedQuery(name = "Usermaster.findByEmail", query = "SELECT u FROM Usermaster u WHERE u.email = :email"),
#NamedQuery(name = "Usermaster.findByProfilePic", query = "SELECT u FROM Usermaster u WHERE u.profilePic = :profilePic"),
#NamedQuery(name = "Usermaster.findByName", query = "SELECT u FROM Usermaster u WHERE u.name = :name"),
#NamedQuery(name = "Usermaster.findByContactNo", query = "SELECT u FROM Usermaster u WHERE u.contactNo = :contactNo"),
#NamedQuery(name = "Usermaster.findByStatus", query = "SELECT u FROM Usermaster u WHERE u.status = :status")})
public class Usermaster implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 50)
#Column(name = "username")
private String username;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 32)
#Column(name = "password")
private String password;
#Basic(optional = false)
#NotNull
#Lob
#Size(min = 1, max = 65535)
#Column(name = "address")
private String address;
#Basic(optional = false)
#NotNull
#Lob
#Size(min = 1, max = 65535)
#Column(name = "mapLocation")
private String mapLocation;
// #Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//if the field contains email address consider using this annotation to enforce field validation
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 32)
#Column(name = "email")
private String email;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 100)
#Column(name = "profilePic")
private String profilePic;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 50)
#Column(name = "name")
private String name;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 10)
#Column(name = "contactNo")
private String contactNo;
#Basic(optional = false)
#NotNull
#Column(name = "status")
private boolean status;
#OneToOne(cascade = CascadeType.ALL, mappedBy = "usermaster")
private College college;
#OneToOne(cascade = CascadeType.ALL, mappedBy = "usermaster")
private Student student;
#OneToOne(cascade = CascadeType.ALL, mappedBy = "usermaster")
private University university;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "username")
private List<Detailnotification> detailnotificationList;
#OneToOne(cascade = CascadeType.ALL, mappedBy = "usermaster")
private Faculty faculty;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "usermaster")
private List<Groupmaster> groupmasterList;
public Usermaster() {
}
public Usermaster(String username) {
this.username = username;
}
public Usermaster(String username, String password, String address, String mapLocation, String email, String profilePic, String name, String contactNo, boolean status) {
this.username = username;
this.password = password;
this.address = address;
this.mapLocation = mapLocation;
this.email = email;
this.profilePic = profilePic;
this.name = name;
this.contactNo = contactNo;
this.status = status;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getMapLocation() {
return mapLocation;
}
public void setMapLocation(String mapLocation) {
this.mapLocation = mapLocation;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getProfilePic() {
return profilePic;
}
public void setProfilePic(String profilePic) {
this.profilePic = profilePic;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContactNo() {
return contactNo;
}
public void setContactNo(String contactNo) {
this.contactNo = contactNo;
}
public boolean getStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
public College getCollege() {
return college;
}
public void setCollege(College college) {
this.college = college;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public University getUniversity() {
return university;
}
public void setUniversity(University university) {
this.university = university;
}
#XmlTransient
public List<Detailnotification> getDetailnotificationList() {
return detailnotificationList;
}
public void setDetailnotificationList(List<Detailnotification> detailnotificationList) {
this.detailnotificationList = detailnotificationList;
}
public Faculty getFaculty() {
return faculty;
}
public void setFaculty(Faculty faculty) {
this.faculty = faculty;
}
#XmlTransient
public List<Groupmaster> getGroupmasterList() {
return groupmasterList;
}
public void setGroupmasterList(List<Groupmaster> groupmasterList) {
this.groupmasterList = groupmasterList;
}
#Override
public int hashCode() {
int hash = 0;
hash += (username != null ? username.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 Usermaster)) {
return false;
}
Usermaster other = (Usermaster) object;
if ((this.username == null && other.username != null) || (this.username != null && !this.username.equals(other.username))) {
return false;
}
return true;
}
#Override
public String toString() {
return "entity.Usermaster[ username=" + username + " ]";
}
}
The medthod in Statless Bean
#Override
public List<University> getAllUniversitys() {
try {
return em.createNamedQuery("University.findAll").getResultList();
} catch (Exception e) {
System.out.println("Error :- " + e.getMessage());
}
return null;
}
The Managed Bean code where it is called through Web Service
public List<University> getAllUniversity() {
try {
adminService.AdminBl adminPort = service.getAdminBlPort();
return adminPort.getAllUniversitys();
//return oAdminBlLocal.getAllUniversitys();
} catch (Exception e) {
System.out.println("Error :- " + e.getMessage());
}
return null;
}
And this is the error:
Severe: Error occured
javax.xml.ws.WebServiceException: javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.SAXException2: A cycle is detected in the object graph. This will cause infinitely deep XML: entity.University[ universityUname=abc ] -> entity.Usermaster[ username=abc ] -> entity.University[ universityUname=abc ]]
at com.sun.xml.ws.message.jaxb.JAXBMessage.writePayloadTo(JAXBMessage.java:424)
at com.sun.xml.ws.message.AbstractMessageImpl.writeTo(AbstractMessageImpl.java:192)
at com.sun.xml.ws.api.message.saaj.SAAJFactory.readAsSOAPMessage(SAAJFactory.java:285)
at com.sun.xml.ws.api.message.saaj.SAAJFactory.read(SAAJFactory.java:163)
at com.sun.xml.ws.message.AbstractMessageImpl.readAsSOAPMessage(AbstractMessageImpl.java:249)
at org.glassfish.webservices.SOAPMessageContextImpl.getMessage(SOAPMessageContextImpl.java:90)
at org.glassfish.webservices.monitoring.MessageTraceImpl.setMessageContext(MessageTraceImpl.java:121)
at org.glassfish.webservices.monitoring.JAXWSEndpointImpl.processResponse(JAXWSEndpointImpl.java:113)
at org.glassfish.webservices.MonitoringPipe.process(MonitoringPipe.java:150)
at com.sun.xml.ws.api.pipe.helper.PipeAdapter.processRequest(PipeAdapter.java:119)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:1136)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:1050)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:1019)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:877)
at com.sun.xml.ws.api.pipe.helper.AbstractTubeImpl.process(AbstractTubeImpl.java:136)
at com.sun.enterprise.security.webservices.CommonServerSecurityPipe.processRequest(CommonServerSecurityPipe.java:209)
at com.sun.enterprise.security.webservices.CommonServerSecurityPipe.process(CommonServerSecurityPipe.java:141)
at com.sun.xml.ws.api.pipe.helper.PipeAdapter.processRequest(PipeAdapter.java:119)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:1136)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:1050)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:1019)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:877)
at com.sun.xml.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:419)
at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:868)
at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:422)
at com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:169)
at org.glassfish.webservices.Ejb3MessageDispatcher.handlePost(Ejb3MessageDispatcher.java:110)
at org.glassfish.webservices.Ejb3MessageDispatcher.invoke(Ejb3MessageDispatcher.java:80)
at org.glassfish.webservices.EjbWebServiceServlet.dispatchToEjbEndpoint(EjbWebServiceServlet.java:210)
at org.glassfish.webservices.EjbWebServiceServlet.service(EjbWebServiceServlet.java:153)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.glassfish.grizzly.servlet.ServletHandler.doServletService(ServletHandler.java:223)
at org.glassfish.grizzly.servlet.ServletHandler.service(ServletHandler.java:174)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.SAXException2: A cycle is detected in the object graph. This will cause infinitely deep XML: entity.University[ universityUname=abc ] -> entity.Usermaster[ username=abc ] -> entity.University[ universityUname=abc ]]
at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:276)
at com.sun.xml.bind.v2.runtime.BridgeImpl.marshal(BridgeImpl.java:94)
at com.sun.xml.bind.api.Bridge.marshal(Bridge.java:111)
at com.sun.xml.ws.db.glassfish.BridgeWrapper.marshal(BridgeWrapper.java:192)
at com.sun.xml.ws.message.jaxb.JAXBMessage.writePayloadTo(JAXBMessage.java:417)
... 51 more
Thanks in advance.
The error is really self-explanatory: A cycle is detected in the object graph. This will cause infinitely deep XML: entity.University[ universityUname=abc ] -> entity.Usermaster[ username=abc ] -> entity.University[ universityUname=abc ]]
Just add #XmlTransient to Usermaster.getUniversity() to break the cycle.
Related
What is the smartest way to get an entity with a field of type List<List> persisted?
#Entity
#Table(name = "Final_Feign_Client_Result")
public class FinalFCResultEntity {
#Id
#Column(name = "id")
#GeneratedValue(strategy = IDENTITY)
private Integer id;
#ElementCollection(targetClass = Object.class)
#CollectionTable(name = "Final_Feign_Client_Result_Columns")
#OnDelete(action = OnDeleteAction.CASCADE)
#JoinColumn(name = "final_feign_client_result_entity_id", nullable = false)
private Set<Object> values;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Set<Object> getValues() {
return values;
}
public void setValues(Set<Object> values) {
this.values = values;
}
}
I have no problem with columns, but if I try to insert values I get this exception:
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.List, at table: final_feign_client_result_columns, for columns: [org.hibernate.mapping.Column(values)]
How I can solve this problem?
Hi guidop21 please add
#ElementCollection(targetClass = Object.class)
#CollectionTable(name = "Final_Feign_Client_Result_Columns")
#OnDelete(action = OnDeleteAction.CASCADE)
#JoinColumn(name = "final_feign_client_result_entity_id", nullable = false)
#OneToMany
private List<List<<Object>> values;
I am trying to perform simple test of reading method. I am trying to work with reactive approach so to test whole context I am using WebTestClient. Although post method seems to work correctly reading operation is not working. But why? Isn't it should be saved to embedded mongo database?
Do I need to wait for it somehow if this is reactive?
Exception is thrown definitely in service because I am seeing
com.geborskimateusz.util.exceptions.NotFoundException: No product found for productId: 1
This is how test looks like:
#ExtendWith(SpringExtension.class)
#SpringBootTest(webEnvironment = RANDOM_PORT, properties = {"spring.data.mongodb.port: 0"})
public class MovieServiceApplicationTests {
#Autowired
WebTestClient webTestClient;
#Autowired
MovieService movieService;
#Test
public void getMovie() {
Integer given = 1;
postAndVerify(given, HttpStatus.OK);
Movie movie = movieService.getMovie(given); **fails here**
assertNotNull(movie);
getAndVerify(given, HttpStatus.OK);
}
private WebTestClient.BodyContentSpec postAndVerify(Integer id, HttpStatus httpStatus) {
Movie movie = Movie.builder()
.movieId(id)
.title("Title for movie " + id)
.genre("Genre for movie " + id)
.address("Address for movie " + id)
.build();
return webTestClient.post()
.uri("/movie")
.body(Mono.just(movie), Movie.class)
.accept(MediaType.APPLICATION_JSON_UTF8)
.exchange()
.expectStatus().isEqualTo(httpStatus)
.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
.expectBody();
}
private WebTestClient.BodyContentSpec getAndVerify(Integer id, HttpStatus httpStatus) {
return webTestClient.get()
.uri("/movie/" + id)
.accept(MediaType.APPLICATION_JSON_UTF8)
.exchange()
.expectStatus().isEqualTo(httpStatus)
.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
.expectBody()
.jsonPath("$.movieId").isEqualTo(id)
.jsonPath("$.genre").isNotEmpty()
.jsonPath("$.title").isNotEmpty()
.jsonPath("$.address").isNotEmpty();
}
}
Service and repository are very simple implementations:
Service:
#Slf4j
#RestController
public class BaseMovieService implements MovieService {
private final ServiceUtil serviceUtil;
private final MovieRepository movieRepository;
private final MovieMapper movieMapper = MovieMapper.INSTANCE;
#Autowired
public BaseMovieService(ServiceUtil serviceUtil, MovieRepository movieRepository) {
this.serviceUtil = serviceUtil;
this.movieRepository = movieRepository;
}
#Override
public Movie getMovie(Integer movieId) {
if (movieId < 1) throw new InvalidInputException("Invalid productId: " + movieId);
MovieEntity movieEntity = movieRepository.findMovieById(movieId)
.orElseThrow(() -> new NotFoundException("No product found for productId: " + movieId));
Movie movie = movieMapper.entityToApi(movieEntity);
movie.setAddress(serviceUtil.getServiceAddress());
log.debug("/movie return the found movie for movieId={}", movieId);
return movie;
}
#Override
public Movie createMovie(Movie movie) {
try {
MovieEntity movieEntity = movieMapper.apiToEntity(movie);
MovieEntity saved = movieRepository.save(movieEntity);
log.debug("createMovie: entity created for movieId: {}", movie.getMovieId());
return movieMapper.entityToApi(saved);
}catch (DuplicateKeyException e) {
throw new InvalidInputException("Duplicate key for movieId: " +movie.getMovieId());
}
}
#Override
public void deleteMovie(Integer movieId) {
}
}
And repo:
public interface MovieRepository extends PagingAndSortingRepository<MovieEntity, String> {
Optional<MovieEntity> findMovieById(Integer movieId);
}
This is however strange because I am sure that repo work fine, all tests below are passing:
#ExtendWith(SpringExtension.class)
#DataMongoTest
public class MovieRepositoryTest {
public static final int BASE_MOVIE_ID = 1;
#Autowired
MovieRepository movieRepository;
MovieEntity savedMovieEntity;
#BeforeEach
void setUp() {
movieRepository.deleteAll();
MovieEntity movieEntity = MovieEntity
.builder()
.movieId(BASE_MOVIE_ID)
.title("Raise of Jedi")
.address("123.321.54x24")
.genre("Sci-Fi")
.build();
savedMovieEntity = movieRepository.save(movieEntity);
assertEqualsMovie(movieEntity, savedMovieEntity);
}
#Test
void create() {
MovieEntity movieEntity = MovieEntity
.builder()
.movieId(2)
.title("Fall of Jedi")
.address("125.721.54x24")
.genre("Sci-Fi")
.build();
MovieEntity saved = movieRepository.save(movieEntity);
assertEqualsMovie(movieEntity, saved);
assertEquals(2, movieRepository.count());
}
#Test
void update() {
String givenTitle = "Updated Title";
savedMovieEntity.setTitle(givenTitle);
MovieEntity updated = movieRepository.save(savedMovieEntity);
assertEquals(givenTitle, updated.getTitle());
}
#Test
void findById() {
Optional<MovieEntity> optionalMovieEntity = movieRepository.findById(savedMovieEntity.getId());
assertTrue(optionalMovieEntity.isPresent());
MovieEntity movieEntity = optionalMovieEntity.get();
assertEqualsMovie(savedMovieEntity, movieEntity);
}
#Test
void shouldPerformOptimisticLocking() {
String concurrentM1actionData = "Concurrent action data performed on M1";
String concurrentM2actionData = "Concurrent action data performed on M2";
MovieEntity m1 = movieRepository.findById(savedMovieEntity.getId()).get();
MovieEntity m2 = movieRepository.findById(savedMovieEntity.getId()).get();
m1.setTitle(concurrentM1actionData);
// by updating Entity its version should be updated
movieRepository.save(m1);
// should fail because of version mismatch
try {
m2.setTitle(concurrentM2actionData);
movieRepository.save(m2);
fail("Expected an OptimisticLockingFailureException");
} catch (OptimisticLockingFailureException e) {
System.out.println("shouldPerformOptimisticLocking() -> catch OptimisticLockingFailureException");
}
//check current version and state
MovieEntity updatedMovieEntity = movieRepository.findById(savedMovieEntity.getId()).get();
assertEquals(1, (int) updatedMovieEntity.getVersion());
assertEquals(concurrentM1actionData, updatedMovieEntity.getTitle());
}
#Test
void delete() {
movieRepository.delete(savedMovieEntity);
assertEquals(0, movieRepository.count());
}
#Test
void duplicateMovieError() {
MovieEntity duplicate = MovieEntity.builder().build();
duplicate.setId(savedMovieEntity.getId());
assertThrows(DuplicateKeyException.class, () -> movieRepository.save(duplicate));
}
#Test
void paging() {
bulkSaveMovie();
Pageable nextPage = PageRequest.of(0, 4, Sort.Direction.ASC, "movieId");
nextPage = verifyPages(nextPage, "[1, 2, 3, 4]", true);
nextPage = verifyPages(nextPage, "[5, 6, 7, 8]", true);
verifyPages(nextPage, "[9, 10]", false);
}
private Pageable verifyPages(Pageable nextPage, String idsAsString, boolean hasNext) {
Page<MovieEntity> moviePage = movieRepository.findAll(nextPage);
assertEquals(hasNext, moviePage.hasNext());
String ids = moviePage.get().map(MovieEntity::getMovieId).collect(Collectors.toList()).toString();
assertEquals(idsAsString, ids);
return nextPage.next();
}
private void bulkSaveMovie() {
movieRepository.deleteAll();
List<MovieEntity> movies = IntStream.rangeClosed(1, 10)
.mapToObj(i -> MovieEntity.builder()
.movieId(i)
.title("Movie nr: " + i)
.build())
.collect(Collectors.toList());
movieRepository.saveAll(movies);
}
private void assertEqualsMovie(MovieEntity expected, MovieEntity actual) {
assertAll("Executing assertEqualsMovie(..)", () -> {
assertEquals(expected.getId(), actual.getId());
assertEquals(expected.getVersion(), actual.getVersion());
assertEquals(expected.getMovieId(), actual.getMovieId());
assertEquals(expected.getTitle(), actual.getTitle());
assertEquals(expected.getAddress(), actual.getAddress());
assertEquals(expected.getGenre(), actual.getGenre());
});
}
}
I am trying to write a JUnit test case for the following search filter method. I am using Querydsl for the search filter. The following method does not depend on Repository; that is why I am not using mockito. This is the first time I am writing a test case for such a method. Please give any suggestions, if you have any?
public List<Tuple> btnSearchClick(String sClientAcctId, String sAcctDesc, String sInvestigatorName,
String sClientDeptId) throws Exception {
QAccount account = QAccount.account;
QDepartment department = QDepartment.department;
QAccountCPCMapping accountCPCMapping = QAccountCPCMapping.accountCPCMapping;
QInvestigator investigator = QInvestigator.investigator;
JPAQuery<Tuple> query = new JPAQuery<Tuple>(em);
query.select(Projections.bean(Account.class, account.sClientAcctId, account.sAcctDesc, account.sLocation,
Projections.bean(Department.class, department.sDeptName, department.sClientDeptId).as("department"),
Projections.bean(Investigator.class, investigator.sInvestigatorName).as("investigator"),
Projections.bean(AccountCPCMapping.class, accountCPCMapping.sCCPCode).as("accountCPC"))).from(account)
.innerJoin(account.department, department).innerJoin(account.accountCPC, accountCPCMapping)
.innerJoin(account.investigator, investigator).where(account.nInstId.eq(60));
Test case
#Test
public void btnSearchClick() throws Exception {
List<Tuple> account= accountService.btnSearchClick("1124100", sAcctDesc, sInvestigatorName, sClientDeptId);
Department dep = new Department();
dep.setsDeptName("Deans Office");
dep.setsClientDeptId("120010");
Investigator invest = new Investigator();
invest.setsInvestigatorName("Ram, Sri");
AccountCPCMapping cpc = new AccountCPCMapping();
cpc.setsCCPCode("RT");
Account acc = new Account();
acc.setsLocation("ON");
acc.setsAcctDesc("SRIRAM");
acc.setsClientAcctId("1124100");
acc.setInvestigator(invest);
acc.setDepartment(dep);
acc.setAccountCPC(cpc);
accountRepo.save(acc);
assertEquals(acc.getsLocation(), account.get(0));
}
Account.java
#Entity
#Table(name = "account")
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Account implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "account_seq_generator")
#SequenceGenerator(name = "account_seq_generator", sequenceName = "account_seq")
#Column(name = "naccount_id")
public Integer nAccountId;
#Column(name = "namount")
public String nAmount;
#Column(name = "sacct_desc")
public String sAcctDesc;
#Column(name = "naccount_cpc_mapping_id")
public Integer nAccountCPCMappingId;
#Column(name = "nindirect_cost_rate")
public Integer nIndiretCostRate;
#Column(name = "nagency_id")
public Integer nAgencyId;
#Column(name = "ndept_id")
public Integer nDeptId;
#Column(name = "sgrant_num")
public String sGrantNum;
#Column(name = "dstart_date")
public Timestamp dStartDate;
#Column(name = "dend_date")
public Timestamp dEndDate;
#Column(name = "slocation")
public String sLocation;
#Column(name = "sclient_acct_id")
public String sClientAcctId;
#Column(name = "ninvestigator_id")
public Integer nInvestigatorId;
#Column(name = "ninst_id")
public Integer nInstId;
#Column(name = "ntemp_account_id")
public Integer nTempAccountId;
#ManyToOne(optional = true, cascade = { CascadeType.MERGE })
#JoinColumn(name = "ndept_id", insertable = false, updatable = false)
public Department department;
#ManyToOne(optional = true, cascade = { CascadeType.ALL })
#JoinColumn(name = "ninvestigator_id", insertable = false, updatable = false)
public Investigator investigator;
#ManyToOne(optional = true, cascade = { CascadeType.ALL })
#JoinColumn(name = "naccount_cpc_mapping_id", insertable = false, updatable = false)
public AccountCPCMapping accountCPC;
// Getter and Setter
Stack Trace
java.lang.AssertionError: expected:<ON> but was:<com.spacestudy.model.Account#783f5f71>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:834)
at org.junit.Assert.assertEquals(Assert.java:118)
at org.junit.Assert.assertEquals(Assert.java:144)
at com.spacestudy.service.TestAccountService.btnSearchClick(TestAccountService.java:120)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
Output from postman
[
{
"sAcctDesc": "SRIRAM",
"sLocation": "ON",
"sClientAcctId": "1124100",
"department": {
"sDeptName": "Deans Office",
"sClientDeptId": "120010"
},
"investigator": {
"sInvestigatorName": "Ram, Sri"
},
"accountCPC": {
"sCCPCode": "RT"
}
}
]
Can anyone please tell me what I am doing wrong in my test case, or suggest an alternative to the code above.
Lists are zero-indexed. That means that if your list has only 1 element, it's index will be 0, not 1.
The element with index 1 is actually the second one (which doesn't exist, thus the index out of bounds).
account.get(1)
should be
account.get(0);
I'm trying to create a simple get request using jersey
but got exception
can someone tell me where I got it wrong?
The excption is - "Caused by: org.glassfish.jersey.server.model.ModelValidationException: Validation of the application resource model has failed during application initialization.
"
VersionResource.java
#Path("/versions")
public class VersionResource extends BaseResource<VersionDao, VersionTable>
{
public VersionResource(VersionDao objectDao)
{
super(objectDao);
}
#Override
#Path("/getAppVersions")
#GET
#UnitOfWork
public String getAllRecords(#Context HttpServletRequest req, #QueryParam("callback") String callback) throws JsonProcessingException
{
return super.getAllRecords(req, callback);
}
}
VersionTable.java
#Entity(name = "Versions")
#Table(name = "Versions")
#NamedQueries({ #NamedQuery(name = QueryNames.QUERY_VERSION_GET_ALL, query = "select c from Versions c"), })
public class VersionTable extends baseDataBase implements Serializable
{
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "VersionId")
private short versionId;
#Column(name = "VersionPlatform")
#JsonProperty
#NotEmpty
private String versionPlatform;
#Column(name = "VersionNumber")
#JsonProperty
#NotEmpty
private String versionNumber;
#Column(name = "VersionDescription")
#JsonProperty
#NotEmpty
private String versionDescription;
public short getVersionId()
{
return versionId;
}
public void setVersionId(short versionId)
{
this.versionId = versionId;
}
public String VersionPlatformEnum()
{
return versionPlatform;
}
public void setVersionPlatform(String versionPlatform)
{
this.versionPlatform = versionPlatform;
}
public String getVersionNumber()
{
return versionNumber;
}
public void setVersionNumber(String versionNumber)
{
this.versionNumber = versionNumber;
}
public String getVersionDescription()
{
return versionDescription;
}
public void setVersionDescription(String versionDescription)
{
this.versionDescription = versionDescription;
}
}
VersionDao.java
public class VersionDao extends baseAbstractDao<VersionTable> implements IDatabaseActions<VersionTable>
{
public VersionDao(SessionFactory sessionFactory)
{
super(sessionFactory);
}
#Override
public ObjectDaoResponse getAllTableRecords() throws JsonProcessingException
{
List<VersionTable> list = list(namedQuery(QueryNames.QUERY_VERSION_GET_ALL));
return ObjectDaoResponse.getAnOkResponse(list);
}
}
I think you need a no arg constructor for your VersionResource class, but if you really need an argument the value should be passed by injection (see: https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/jaxrs-resources.html#d0e2692)
hope somebaody can help me. I have two entities related OneToMany.
First:
#Entity
#Table(name = "repartos")
#XmlRootElement
public class Repartos 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 = "fecha")
#Temporal(TemporalType.DATE)
private Date fecha;
#OneToMany(cascade = {CascadeType.ALL}, mappedBy = "repartoId")
public List<RepartosDetalle> repartosDetalleList;
.....
And then the another one:
#Entity
#Table(name = "repartos_detalle")
#XmlRootElement
public class RepartosDetalle implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#JoinColumn(name = "reparto_id", referencedColumnName = "id")
#ManyToOne(optional = false)
private Repartos repartoId;
#Column(name = "descargado")
#Convert(converter = BooleanOneZeroConverter.class)
private boolean descargado;
public RepartosDetalle() {
}
public RepartosDetalle(Repartos repartoId) {
this.repartoId = repartoId;
}
public Repartos getRepartoId() {
return repartoId;
}
public void setRepartoId(Repartos repartoId) {
this.repartoId = repartoId;
}
public boolean isDescargado() {
return descargado;
}
public void setDescargado(boolean descargado) {
this.descargado = descargado;
}
}
What I try to get is all the Repartos given a date and where they have al least one RepartosDetalle with the property descargado=TRUE.
I've been trying with the following query but I do't get any result.
#Override
public List<Repartos> buscarPorFechaDescargados(Date searchDate) {
Query q = em.createQuery("SELECT e FROM Repartos e "
+ "WHERE e.fecha = :searchDate"
+ " AND e.repartosDetalleList.descargado=TRUE");
q.setParameter("searchDate", searchDate);
return q.getResultList();
}
Is there a proper way to make this query using one of the collection's property value?
Thanks a lot and nice weekend.
Try to use JOIN operator on these 2 entities - Repartos and RepartosDetalle :
SELECT e FROM Repartos e JOIN RepartosDetalle d
WHERE e.fecha = :searchDate
AND d.descargado = TRUE