Hibernate makes unnecessary subquery to fetch data - java
I'm using Spring Boot 2.x, Spring Data REST, Spring HATEOAS.
I'm exposing a Repository over REST:
#Transactional
#PreAuthorize("isAuthenticated()")
public interface DocumentRepository extends JpaRepository<Document, Long>, JpaSpecificationExecutor {
#Transactional(readOnly = true)
#Query("SELECT d FROM Document d LEFT JOIN FETCH Contact c ON d.contact.id=c.id WHERE d.type='SALES_ORDER' AND d.status='PENDING' AND d.store.id=:storeId AND (SELECT COUNT(row) FROM DocumentRow row JOIN ProductAvailability pa ON (pa.productCode=row.productCode AND pa.productType=row.productType) WHERE row.document.id=d.id AND row.product.id IS NOT NULL AND pa.qtyOnHand-pa.qtyAllocated < row.qty)=0")
Page<Document> findOrdersReadyToProcess(#Param("storeId") Long storeId, Pageable pageable);
Because I need some information of the Contact, I'm using a Spring Projection defined as:
#org.springframework.data.rest.core.config.Projection(name = "table", types = {Document.class})
public interface Projection {
Instant getCreatedDate();
Instant getDate();
boolean isElectronic();
BigDecimal getTotalAmount();
DocumentType getType();
String getCode();
String getFiscalReceiptNumber();
String getPurchaseRefCode();
DocumentStatus getStatus();
DocumentDeliveryStatus getDeliveryStatus();
boolean isAssemble();
ContactProjection getContact();
StoreProjection getStore();
}
and the ContactProjection is:
#Projection(types = {Contact.class})
public interface ContactProjection {
String getFullName();
}
Contact is defines as follows in Document entity:
#JsonDeserialize(using = ContactUriDeserializer.class)
#ManyToOne(fetch = FetchType.LAZY)
private Contact contact;
However, when I call the endpoint Hibernate do N subquery to fetch Contact information:
Hibernate: select document0_.`id` as id1_12_, document0_.`createdBy` as createdB2_12_, document0_.`createdDate` as createdD3_12_, document0_.`lastModifiedBy` as lastModi4_12_, document0_.`lastModifiedDate` as lastModi5_12_, document0_.`sid` as sid6_12_, document0_.`version` as version7_12_, document0_.`amount` as amount8_12_, document0_.`assemble` as assemble9_12_, document0_.`code` as code10_12_, document0_.`contact_id` as contact36_12_, document0_.`costAmount` as costAmo11_12_, document0_.`date` as date12_12_, document0_.`deliveryDate` as deliver13_12_, document0_.`deliveryStatus` as deliver14_12_, document0_.`destinationStore_id` as destina37_12_, document0_.`electronic` as electro15_12_, document0_.`embeddedContact` as embedde16_12_, document0_.`eyeExam_id` as eyeExam38_12_, document0_.`fiscalReceiptDate` as fiscalR17_12_, document0_.`fiscalReceiptNumber` as fiscalR18_12_, document0_.`fiscalReceiptPrintDate` as fiscalR19_12_, document0_.`fiscalReceiptSerialNumber` as fiscalR20_12_, document0_.`grossMargin` as grossMa21_12_, document0_.`grossProfit` as grossPr22_12_, document0_.`number` as number23_12_, document0_.`numberSeries` as numberS24_12_, document0_.`paymentTerm_id` as payment39_12_, document0_.`paymentType` as payment25_12_, document0_.`project_id` as project40_12_, document0_.`purchaseRefCode` as purchas26_12_, document0_.`rounding` as roundin27_12_, document0_.`sourceStore_id` as sourceS41_12_, document0_.`status` as status28_12_, document0_.`store_id` as store_i42_12_, document0_.`stsTaxDeductionDenial` as stsTaxD29_12_, document0_.`supplyType` as supplyT30_12_, document0_.`taxAmount` as taxAmou31_12_, document0_.`totalAmount` as totalAm32_12_, document0_.`type` as type33_12_, document0_.`workingDistance` as working34_12_, document0_.`year` as year35_12_ from `Document` document0_ left outer join `Contact` contact1_ on (document0_.`contact_id`=contact1_.`id`) where document0_.`type`='SALES_ORDER' and document0_.`status`='PENDING' and document0_.`store_id`=? and (select count(documentro2_.`id`) from `DocumentRow` documentro2_ inner join `ProductAvailability` productava3_ on (productava3_.`productCode`=documentro2_.`productCode` and productava3_.`productType`=documentro2_.`productType`) where documentro2_.`document_id`=document0_.`id` and (documentro2_.`product_id` is not null) and productava3_.`qtyOnHand`-productava3_.`qtyAllocated`<documentro2_.`qty`)=0 limit ?
Hibernate: select contact0_.`id` as id1_6_0_, contact0_.`createdBy` as createdB2_6_0_, contact0_.`createdDate` as createdD3_6_0_, contact0_.`lastModifiedBy` as lastModi4_6_0_, contact0_.`lastModifiedDate` as lastModi5_6_0_, contact0_.`sid` as sid6_6_0_, contact0_.`version` as version7_6_0_, contact0_.`billingAddress` as billingA8_6_0_, contact0_.`billingCity` as billingC9_6_0_, contact0_.`billingCountry` as billing10_6_0_, contact0_.`billingDistrict` as billing11_6_0_, contact0_.`billingZipCode` as billing12_6_0_, contact0_.`birthCity` as birthCi13_6_0_, contact0_.`birthDate` as birthDa14_6_0_, contact0_.`certifiedEmail` as certifi15_6_0_, contact0_.`companyName` as company16_6_0_, contact0_.`email` as email17_6_0_, contact0_.`fax` as fax18_6_0_, contact0_.`firstName` as firstNa19_6_0_, contact0_.`fullName` as fullNam20_6_0_, contact0_.`gender` as gender21_6_0_, contact0_.`iban` as iban22_6_0_, contact0_.`job` as job23_6_0_, contact0_.`landlinePhone` as landlin24_6_0_, contact0_.`lastName` as lastNam25_6_0_, contact0_.`mobilePhone` as mobileP26_6_0_, contact0_.`personType` as personT27_6_0_, contact0_.`preset` as preset28_6_0_, contact0_.`publicAdministration` as publicA29_6_0_, contact0_.`sdiAccountId` as sdiAcco30_6_0_, contact0_.`shippingAddress` as shippin31_6_0_, contact0_.`shippingCity` as shippin32_6_0_, contact0_.`shippingCountry` as shippin33_6_0_, contact0_.`shippingDistrict` as shippin34_6_0_, contact0_.`shippingZipCode` as shippin35_6_0_, contact0_.`store_id` as store_i45_6_0_, contact0_.`computerUser` as compute36_6_0_, contact0_.`drivingFrequency` as driving37_6_0_, contact0_.`electronicDeviceUser` as electro38_6_0_, contact0_.`jobCategory` as jobCate39_6_0_, contact0_.`sporty` as sporty40_6_0_, contact0_.`swift` as swift41_6_0_, contact0_.`taxCode` as taxCode42_6_0_, contact0_.`type` as type43_6_0_, contact0_.`vatNumber` as vatNumb44_6_0_ from `Contact` contact0_ where contact0_.`id`=?
Hibernate: select store0_.`id` as id1_40_0_, store0_.`createdBy` as createdB2_40_0_, store0_.`createdDate` as createdD3_40_0_, store0_.`lastModifiedBy` as lastModi4_40_0_, store0_.`lastModifiedDate` as lastModi5_40_0_, store0_.`sid` as sid6_40_0_, store0_.`version` as version7_40_0_, store0_.`address` as address8_40_0_, store0_.`certifiedEmail` as certifie9_40_0_, store0_.`city` as city10_40_0_, store0_.`code` as code11_40_0_, store0_.`country` as country12_40_0_, store0_.`district` as distric13_40_0_, store0_.`email` as email14_40_0_, store0_.`fax` as fax15_40_0_, store0_.`landlinePhone` as landlin16_40_0_, store0_.`mobilePhone` as mobileP17_40_0_, store0_.`name` as name18_40_0_, store0_.`zipCode` as zipCode19_40_0_ from `Store` store0_ where store0_.`id`=?
Hibernate: select contact0_.`id` as id1_6_0_, contact0_.`createdBy` as createdB2_6_0_, contact0_.`createdDate` as createdD3_6_0_, contact0_.`lastModifiedBy` as lastModi4_6_0_, contact0_.`lastModifiedDate` as lastModi5_6_0_, contact0_.`sid` as sid6_6_0_, contact0_.`version` as version7_6_0_, contact0_.`billingAddress` as billingA8_6_0_, contact0_.`billingCity` as billingC9_6_0_, contact0_.`billingCountry` as billing10_6_0_, contact0_.`billingDistrict` as billing11_6_0_, contact0_.`billingZipCode` as billing12_6_0_, contact0_.`birthCity` as birthCi13_6_0_, contact0_.`birthDate` as birthDa14_6_0_, contact0_.`certifiedEmail` as certifi15_6_0_, contact0_.`companyName` as company16_6_0_, contact0_.`email` as email17_6_0_, contact0_.`fax` as fax18_6_0_, contact0_.`firstName` as firstNa19_6_0_, contact0_.`fullName` as fullNam20_6_0_, contact0_.`gender` as gender21_6_0_, contact0_.`iban` as iban22_6_0_, contact0_.`job` as job23_6_0_, contact0_.`landlinePhone` as landlin24_6_0_, contact0_.`lastName` as lastNam25_6_0_, contact0_.`mobilePhone` as mobileP26_6_0_, contact0_.`personType` as personT27_6_0_, contact0_.`preset` as preset28_6_0_, contact0_.`publicAdministration` as publicA29_6_0_, contact0_.`sdiAccountId` as sdiAcco30_6_0_, contact0_.`shippingAddress` as shippin31_6_0_, contact0_.`shippingCity` as shippin32_6_0_, contact0_.`shippingCountry` as shippin33_6_0_, contact0_.`shippingDistrict` as shippin34_6_0_, contact0_.`shippingZipCode` as shippin35_6_0_, contact0_.`store_id` as store_i45_6_0_, contact0_.`computerUser` as compute36_6_0_, contact0_.`drivingFrequency` as driving37_6_0_, contact0_.`electronicDeviceUser` as electro38_6_0_, contact0_.`jobCategory` as jobCate39_6_0_, contact0_.`sporty` as sporty40_6_0_, contact0_.`swift` as swift41_6_0_, contact0_.`taxCode` as taxCode42_6_0_, contact0_.`type` as type43_6_0_, contact0_.`vatNumber` as vatNumb44_6_0_ from `Contact` contact0_ where contact0_.`id`=?
Hibernate: select contact0_.`id` as id1_6_0_, contact0_.`createdBy` as createdB2_6_0_, contact0_.`createdDate` as createdD3_6_0_, contact0_.`lastModifiedBy` as lastModi4_6_0_, contact0_.`lastModifiedDate` as lastModi5_6_0_, contact0_.`sid` as sid6_6_0_, contact0_.`version` as version7_6_0_, contact0_.`billingAddress` as billingA8_6_0_, contact0_.`billingCity` as billingC9_6_0_, contact0_.`billingCountry` as billing10_6_0_, contact0_.`billingDistrict` as billing11_6_0_, contact0_.`billingZipCode` as billing12_6_0_, contact0_.`birthCity` as birthCi13_6_0_, contact0_.`birthDate` as birthDa14_6_0_, contact0_.`certifiedEmail` as certifi15_6_0_, contact0_.`companyName` as company16_6_0_, contact0_.`email` as email17_6_0_, contact0_.`fax` as fax18_6_0_, contact0_.`firstName` as firstNa19_6_0_, contact0_.`fullName` as fullNam20_6_0_, contact0_.`gender` as gender21_6_0_, contact0_.`iban` as iban22_6_0_, contact0_.`job` as job23_6_0_, contact0_.`landlinePhone` as landlin24_6_0_, contact0_.`lastName` as lastNam25_6_0_, contact0_.`mobilePhone` as mobileP26_6_0_, contact0_.`personType` as personT27_6_0_, contact0_.`preset` as preset28_6_0_, contact0_.`publicAdministration` as publicA29_6_0_, contact0_.`sdiAccountId` as sdiAcco30_6_0_, contact0_.`shippingAddress` as shippin31_6_0_, contact0_.`shippingCity` as shippin32_6_0_, contact0_.`shippingCountry` as shippin33_6_0_, contact0_.`shippingDistrict` as shippin34_6_0_, contact0_.`shippingZipCode` as shippin35_6_0_, contact0_.`store_id` as store_i45_6_0_, contact0_.`computerUser` as compute36_6_0_, contact0_.`drivingFrequency` as driving37_6_0_, contact0_.`electronicDeviceUser` as electro38_6_0_, contact0_.`jobCategory` as jobCate39_6_0_, contact0_.`sporty` as sporty40_6_0_, contact0_.`swift` as swift41_6_0_, contact0_.`taxCode` as taxCode42_6_0_, contact0_.`type` as type43_6_0_, contact0_.`vatNumber` as vatNumb44_6_0_ from `Contact` contact0_ where contact0_.`id`=?
Hibernate: select contact0_.`id` as id1_6_0_, contact0_.`createdBy` as createdB2_6_0_, contact0_.`createdDate` as createdD3_6_0_, contact0_.`lastModifiedBy` as lastModi4_6_0_, contact0_.`lastModifiedDate` as lastModi5_6_0_, contact0_.`sid` as sid6_6_0_, contact0_.`version` as version7_6_0_, contact0_.`billingAddress` as billingA8_6_0_, contact0_.`billingCity` as billingC9_6_0_, contact0_.`billingCountry` as billing10_6_0_, contact0_.`billingDistrict` as billing11_6_0_, contact0_.`billingZipCode` as billing12_6_0_, contact0_.`birthCity` as birthCi13_6_0_, contact0_.`birthDate` as birthDa14_6_0_, contact0_.`certifiedEmail` as certifi15_6_0_, contact0_.`companyName` as company16_6_0_, contact0_.`email` as email17_6_0_, contact0_.`fax` as fax18_6_0_, contact0_.`firstName` as firstNa19_6_0_, contact0_.`fullName` as fullNam20_6_0_, contact0_.`gender` as gender21_6_0_, contact0_.`iban` as iban22_6_0_, contact0_.`job` as job23_6_0_, contact0_.`landlinePhone` as landlin24_6_0_, contact0_.`lastName` as lastNam25_6_0_, contact0_.`mobilePhone` as mobileP26_6_0_, contact0_.`personType` as personT27_6_0_, contact0_.`preset` as preset28_6_0_, contact0_.`publicAdministration` as publicA29_6_0_, contact0_.`sdiAccountId` as sdiAcco30_6_0_, contact0_.`shippingAddress` as shippin31_6_0_, contact0_.`shippingCity` as shippin32_6_0_, contact0_.`shippingCountry` as shippin33_6_0_, contact0_.`shippingDistrict` as shippin34_6_0_, contact0_.`shippingZipCode` as shippin35_6_0_, contact0_.`store_id` as store_i45_6_0_, contact0_.`computerUser` as compute36_6_0_, contact0_.`drivingFrequency` as driving37_6_0_, contact0_.`electronicDeviceUser` as electro38_6_0_, contact0_.`jobCategory` as jobCate39_6_0_, contact0_.`sporty` as sporty40_6_0_, contact0_.`swift` as swift41_6_0_, contact0_.`taxCode` as taxCode42_6_0_, contact0_.`type` as type43_6_0_, contact0_.`vatNumber` as vatNumb44_6_0_ from `Contact` contact0_ where contact0_.`id`=?
I want to avoid this N+1 SELECT problem! I tried several modification to the query, but every time I ended up to have these subqueries.
Am I doing something wrong? Why Hibernate doesn't fetch contact property and avoid subsequent subqueries?
Any hint would be appreciated.
Try to add the following annotation to your repository method:
#EntityGraph("contact")
Related
How do i check if record already exists use same record else create in java using spring boot
I want to check if user alraedy exits use same data else create new record ` #EventHandler #Override public void on(ContentSaveUserEvent event) { var existingRecord =classesCurriculumMapRepository.findByClassIdAndCurriculumMapId(Long.valueOf(event.getClassId()), event.getCurriculumMapId()); if (!existingRecord.isEmpty()) { // here i want to use same record if already exits based on classid and curriculummapid } else { Class_CurriculumMap classCurriculumMap= new Class_CurriculumMap(); classCurriculumMap.setId(new Class_CurriculumMapPK(Long.valueOf(event.getClassId()), event.getCurriculumMapId())); classCurriculumMap.setDateLastModified(new Date()); classCurriculumMap.setUserLastModified(event.getUctx().getUserId()); classCurriculumMap.setStatus(Status.Active.value); classesCurriculumMapRepository.save(classCurriculumMap); } } } ` the query i am using is: ` #Query(value ="select * from class_curriculummap where ClassId =?1 And CurriculumMapId='?2'", nativeQuery = true) List<Class_CurriculumMap> findByClassIdAndCurriculumMapId(Long classId, String curriculumMapId); The response i am sending from postman is: { "classId": 1388126554733599886, "curriculumMapId":"973BB040ggg16C44C4CA550FA14370499E2" } `
Replace your Query with below: #Query(value ="select exists(select * from class_curriculummap where ClassId =?1 And CurriculumMapId='?2')", nativeQuery = true) boolean isExists findByClassIdAndCurriculumMapId(Long classId, String curriculumMapId); For more details, please refer to this article : Check if a row exists, otherwise insert
spring-data-mongodb #Update annotation with arrayFilters
spring-data-mongodb 3.4.0 have a beautiful #Update annotation support for jpa repositories. But how can i pass arrayFilters and other options, supported by https://www.mongodb.com/docs/manual/reference/method/db.collection.update/ ? Here is my working manual example: public #NotNull Comment addComment(String id, String cid, String lid, String sid, Comment comment) { // Add comment JwtUser user = userService.getCurrentUser().orElseThrow(() -> new SodixException("Can't get current user")); EditorUser author = EditorUser.builder() .id(user.getExternalId()) .username(user.getUsername()) .firstName(user.getFirstName()) .lastName(user.getLastName()) .build(); CommentEntity commentToSave = new CommentEntity(); commentToSave.setId(ProjectIdUtil.generateCommentId()); commentToSave.setCreatedAt(LocalDateTime.now()); commentToSave.setAuthor(author); commentToSave.setMessage(comment.getMessage()); Query query = new Query(); query.addCriteria(Criteria.where("_id").is(id)); query.addCriteria(Criteria.where("chapters").elemMatch( Criteria.where("_id").is(cid).and("lessons").elemMatch( Criteria.where("_id").is(lid).and("sections").elemMatch( Criteria.where("_id").is(sid) ) ) )); Update update = new Update(); update.addToSet("chapters.$[c].lessons.$[l].sections.$[s].comments", commentToSave); update.filterArray("c._id", cid); update.filterArray("l._id", lid); update.filterArray("s._id", sid); var result = mongoTemplate.updateFirst(query, update, ProjectEntity.class); if (result.getModifiedCount() < 1) { throw new RuntimeException("Comment wasn't added"); } } Here is what i expect to run using repository #Update annotation, but it's not working yet: import org.springframework.data.mongodb.repository.Query; import org.springframework.data.mongodb.repository.Update; ... #Repository public interface ProjectRepository extends MongoRepository<ProjectEntity, String> { ... #Query("{ _id : ?0, chapters : {$elemMatch : {_id: ?1, lessons: {$elemMatch: {_id: ?2, 'sections._id': ?3}}}}}") #Update("{$set : { 'chapters.$[c].lessons.$[l].sections.$[s].comments' : ?4 }, $arrayFilters: {'c._id': ?1, 'l._id': ?2, 's._id': ?3}}") long addComment(String id, String cid, String lid, String sid, CommentEntity comment); ... } Error i've got is: com.mongodb.MongoWriteException: Write operation error on server localhost:27017. Write error: WriteError{code=2, message='No array filter found for identifier 'c' in path 'chapters.$[c].lessons.$[l].sections.$[s].comments'', details={}}. Thanks for the help!
HQL order by for two different fileds
I want to select data from Workflow table using order by.How to do so? public Workflow getDocById(String id) { Query queryWfManager = sessionfactory.getCurrentSession().createQuery("from Workflow where id =:id"); queryWfManager.setParameter("id", id); Workflow wfManagerList = (Workflow) queryWfManager.list(); Query queryWfDetails = sessionfactory.getCurrentSession().createQuery("from WorkflowDetails where workflowCode =:workflowCode order by wfBlockId order by stepSeq"); queryWfDetails.setParameter("workflowCode", wfManagerList.getWorkflowCode()); List<WorkflowDetails> queryWfDetailList = queryWfDetails.list(); wfManagerList.setSteps(queryWfDetailList); return wfManagerList; } Which One is correct Writing oreder by order by wfBlockId , stepSeq OR order by wfBlockId order by stepSeq? public Workflow getDocById(String id) { Query queryWfManager = sessionfactory.getCurrentSession().createQuery("from Workflow where id =:id"); queryWfManager.setParameter("id", id); Workflow wfManagerList = (Workflow) queryWfManager.list(); Query queryWfDetails = sessionfactory.getCurrentSession().createQuery("from WorkflowDetails where workflowCode =:workflowCode order by wfBlockId , stepSeq"); queryWfDetails.setParameter("workflowCode", wfManagerList.getWorkflowCode()); List<WorkflowDetails> queryWfDetailList = queryWfDetails.list(); wfManagerList.setSteps(queryWfDetailList); return wfManagerList; }
Query queryWfDetails = sessionfactory.getCurrentSession() .createQuery("FROM WorkflowDetails where workflowCode =:workflowCode ORDER BY wfBlockId , stepSeq"); The above query is correct.
JPA & PostgreSQL: How do I call a stored procedure using NamedNativeQuery Annotation
Using Postgresql 8.1, Spring 3.0, Hibernate 3.6. I have a method that calls a stored procedure that works without using Annotations, essentially it is .... return (Integer) getJpaTemplate().execute(new JpaCallback() { public Object doInJpa(EntityManager em) { // Query query = em.createNamedQuery("checkZone"); Query query = em.createNativeQuery("select zoneArea from zoneArea(:pId, :zId)"); query.setParameter("pId", p.getId()); query.setParameter("zId", z.getId()); try { return query.getSingleResult(); // Integer expected } catch (NoResultException e) { return 0; } } }); .... How can I do this with Annotations, here's my attempt that does not work. #NamedNativeQueries({ #NamedNativeQuery( name = "checkZone", query = "select zoneArea from zoneArea(:pId, :zId)", hints = { #QueryHint(name = "org.hibernate.callable", value = "true") }, resultSetMapping = "scalar", resultClass = Integer.class)}) #SqlResultSetMapping(name="scalar",columns=#ColumnResult(name="result")) #Entity and here is the Exception Caused by: org.postgresql.util.PSQLException: This statement does not declare an OUT parameter. Use { ?= call ... } to declare one. at org.postgresql.jdbc2.AbstractJdbc2Statement.registerOutParameter(AbstractJdbc2Statement.java:1849) at org.postgresql.jdbc3.AbstractJdbc3Statement.registerOutParameter(AbstractJdbc3Statement.java:1513) at org.hibernate.dialect.PostgreSQLDialect.registerResultSetOutParameter(PostgreSQLDialect.java:335) at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1713) at org.hibernate.loader.Loader.doQuery(Loader.java:801) I have working code but would like to get this working with Annotations, any ideas appreciated.
How to insert values into database using queries using entity manager, persistence using a java class?
I want to insert data into a table using the following code public User registerUser(String usr, String pwd) { u=em.find(User.class,usr); if(u!=null) { return null; } String query1 = "insert into users values('" + usr + "','" + pwd +"')"; Query q = em.createQuery(query1); u=em.find(User.class,usr); return u; } here 'u' is the object of User class and em is EntityManager. I get this following exception: Servlet.service() for servlet action threw exception org.hibernate.hql.ast.QuerySyntaxException: expecting OPEN, found 'values' near line 1, column 19 [insert into users values('pawan','am')]
Try public User registerUser(String usr, String pwd) { u=em.find(User.class,usr); if(u!=null) { return null; } //Now saving... em.getTransaction().begin(); em.persist(u); //em.merge(u); for updates em.getTransaction().commit(); em.close(); return u; } If the PK is Identity, it will be set automatically in your persisted class, if you are using auto generation strategy (thanks to David Victor). Edit to #aman_novice comment: set it in your class //Do this BEFORE getTransaction/persist/commit //Set names are just a example, change it to your class setters u.setUsr(usr); u.setPwd(pwd); //Now you can persist or merge it, as i said in the first example em.getTransaction().begin(); (...) About #David Victor, sorry I forgot about that.
You're not using SQL but JPAQL, there is no field-based insert. You persist object rather than inserting rows. You should do something like this: public User registerUser(String usr, String pwd) { u=em.find(User.class,usr); if(u!=null) { return u; } u = new User(usr, pwd); em.persist(u); return u; }
This isn't really the way to go. You are trying to insert a row in a table but have no associated attached entity. If you're using the JPA entity manager - then create a new instance - set the properties & persist the entity. E.g. User u = new User(); u.setXXX(xx); em.persist(u); // em.flush() <<-- Not required, useful for seeing what is happening // etc.. If you enable SQL loggging in Hibernate & flush the entity then you'll see what is sent to the database. E.g. in persistence.xml: <property name="hibernate.format_sql" value="true" />