From 7f838ba021e65c31174c3c20591b4c75ac343d27 Mon Sep 17 00:00:00 2001 From: Artyom_Yashin Date: Fri, 19 Apr 2024 15:09:26 +0400 Subject: [PATCH] Lab 3 done --- build.gradle | 14 + data.mv.db | Bin 0 -> 40960 bytes data.trace.db | 449 ++++++++++++++++++ src/main/java/ip_2/lab1/Lab1Application.java | 51 +- src/main/java/ip_2/lab1/core/api/PageDto.java | 97 ++++ .../ip_2/lab1/core/api/PageDtoMapper.java | 25 + .../lab1/core/configuration/Constants.java | 2 + .../lab1/core/error/NotFoundException.java | 4 +- .../java/ip_2/lab1/core/model/BaseEntity.java | 9 +- .../core/repository/CommonRepository.java | 13 - .../lab1/core/repository/MapRepository.java | 55 --- .../ip_2/lab1/items/api/ItemController.java | 17 +- .../java/ip_2/lab1/items/api/ItemDto.java | 2 +- .../ip_2/lab1/items/api/ItemGroupedDto.java | 22 + .../ip_2/lab1/items/model/ItemEntity.java | 11 +- .../ip_2/lab1/items/model/ItemGrouped.java | 8 + .../lab1/items/repository/ItemRepository.java | 18 +- .../ip_2/lab1/items/service/ItemService.java | 45 +- .../lab1/reviews/api/ReviewController.java | 40 +- .../java/ip_2/lab1/reviews/api/ReviewDto.java | 17 +- .../lab1/reviews/api/ReviewGroupedDto.java | 22 + .../ip_2/lab1/reviews/model/ReviewEntity.java | 33 +- .../lab1/reviews/model/ReviewGrouped.java | 8 + .../reviews/repository/ReviewRepository.java | 21 +- .../lab1/reviews/service/ReviewService.java | 62 ++- .../ip_2/lab1/types/api/TypeController.java | 1 - .../java/ip_2/lab1/types/api/TypeDto.java | 8 +- .../ip_2/lab1/types/model/TypeEntity.java | 12 +- .../lab1/types/repository/TypeRepository.java | 8 +- .../ip_2/lab1/types/service/TypeService.java | 41 +- .../ip_2/lab1/users/api/UserController.java | 48 ++ .../java/ip_2/lab1/users/api/UserDto.java | 41 ++ .../ip_2/lab1/users/model/UserEntity.java | 68 +++ .../lab1/users/repository/UserRepository.java | 14 + .../ip_2/lab1/users/service/UserService.java | 89 ++++ src/main/resources/application.properties | 19 + src/test/java/ip_2/lab1/ItemServiceTest.java | 88 ++++ .../java/ip_2/lab1/ReviewServiceTest.java | 74 +++ src/test/java/ip_2/lab1/TypeServiceTests.java | 68 ++- src/test/java/ip_2/lab1/UserServiceTest.java | 87 ++++ 40 files changed, 1512 insertions(+), 199 deletions(-) create mode 100644 data.mv.db create mode 100644 data.trace.db create mode 100644 src/main/java/ip_2/lab1/core/api/PageDto.java create mode 100644 src/main/java/ip_2/lab1/core/api/PageDtoMapper.java delete mode 100644 src/main/java/ip_2/lab1/core/repository/CommonRepository.java delete mode 100644 src/main/java/ip_2/lab1/core/repository/MapRepository.java create mode 100644 src/main/java/ip_2/lab1/items/api/ItemGroupedDto.java create mode 100644 src/main/java/ip_2/lab1/items/model/ItemGrouped.java create mode 100644 src/main/java/ip_2/lab1/reviews/api/ReviewGroupedDto.java create mode 100644 src/main/java/ip_2/lab1/reviews/model/ReviewGrouped.java create mode 100644 src/main/java/ip_2/lab1/users/api/UserController.java create mode 100644 src/main/java/ip_2/lab1/users/api/UserDto.java create mode 100644 src/main/java/ip_2/lab1/users/model/UserEntity.java create mode 100644 src/main/java/ip_2/lab1/users/repository/UserRepository.java create mode 100644 src/main/java/ip_2/lab1/users/service/UserService.java create mode 100644 src/test/java/ip_2/lab1/ItemServiceTest.java create mode 100644 src/test/java/ip_2/lab1/ReviewServiceTest.java create mode 100644 src/test/java/ip_2/lab1/UserServiceTest.java diff --git a/build.gradle b/build.gradle index 0329e9e..3d9ae3e 100644 --- a/build.gradle +++ b/build.gradle @@ -7,6 +7,17 @@ plugins { group = 'IP_2' version = '0.0.1-SNAPSHOT' +defaultTasks 'bootRun' + +jar { + enabled = false +} + +bootJar { + archiveFileName = String.format('%s-%s.jar', rootProject.name, version) +} + +assert System.properties['java.specification.version'] == '17' || '21' java { sourceCompatibility = '17' } @@ -20,6 +31,9 @@ dependencies { implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0' implementation 'org.modelmapper:modelmapper:3.2.0' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'com.h2database:h2:2.2.224' + developmentOnly 'org.springframework.boot:spring-boot-devtools' testImplementation 'org.springframework.boot:spring-boot-starter-test' } diff --git a/data.mv.db b/data.mv.db new file mode 100644 index 0000000000000000000000000000000000000000..8cff1cbfd31011e11ff1395ff60f50d2da508b9a GIT binary patch literal 40960 zcmeHQ%X1q^86Vk_J#p+fo5!Yj941N}$B9-u-7`H8!9rwNj+NMQBFTwURN?A*B_@uP za^!5h#bH_AuyEW9C#s-|tpX05D2l@t2a4h(pP={)_!pMT^36*cNuyXM&WmkVS>3Ja z$Jf94y1(w3@7G$&;f%4>Fz@GdKdf%PXXlV8iW&3XPW^sPqe{lyvS~esGUm2To3@oh znr#~vK_(&@r?LHjHgi(uvAz9hvr+d7I9qnpyk~Fcs3a34Th;`}{ulxb0fqoWfFZyT zUh_anPRTSIW)AC?E*#FE>q9WZU*bj*32x-#CmbiQd*R5@FJGADHAB-i zUBnzW{*CFm#K;AXM51q>i! zS+)szOiiSwBlD`InYt`P9?P&rDnZ27sb~;`*FXn|s_8zwL>A9Aw(n-|;p~IQkD85b zJ8K!)^3K-QExNU1FVH5f?LM?w9){27O*b+<3O{gh5zuUC)+uL+EEH%uadk#X5COsjCX`SVH_G#fjcW@ZM zdzC9*6-P%#T&v4X{$p}|WMr0WTU$3mMFfTvTmntYA`-7T6ca4Uye@+Er6PuiMX_b* zypB~%vB0e8GI2~@H+hOR$CMC6G>vE~7*eVkU}G^vbi=@|b)yDF8dzeUnnWQI)!m4u zg0bSMB~dC{m^T!InhKbDLlZUKhPF&Zb&G(xG$maJaVT#R(Nt|H1@_vOZ7`Q6p^oT? zkjIoYFoKvj9nscQu!)x97@~$O-qJKvRYf{(8LC4SnFkALYG9*zTeYYJMwPd9O(s~v zyiLJ=VpZlHq!^YcTD*fT$1*g`I}!mKOBLRcCHO*@AR?=xtZTfZn_!O(#50V1%>G$4&hE%+hG;43`)gO{T`i`6ClYC#Q~0AAjS-$y2A_Jj0z8F05CJHK9-` z=4-```L)vWf`GA{7SdDSOZeXkYt>>!C@l)*)tXRTFI8(*AzjU2YbpsykA#6B? z;ndPEskS5_p;C+_F*+{@Q@;p1R>&8YiVH$5KffHUvs5dtRMQtH+=sjA!s=SNmKI9o zTJb8t;9^i-TVBriS8r5Gh2p@grG>OGU%Coqd&|}C+$e6uT%MSl5zbB(gZ@J8EBVSD z;d=2-q|3p#8}RK0+^E%Z2$}vy`2)oJ`hg5L6R$Pa>Q&`GZ@&&i2 zw*aqF`RYYU6zAHYPt08eRId(=s?vjMTUf96bAapPcwEDbLm>;T91K|{eF>2L`98?H zs@2AIK3^?vKr8=~l9ux;pxbfSMxnh7(B2DYigF1?s5d~W!UD_`rE;Oxr!5if@)W60 zi-RtteF5CzRuvXYm1=D+1K7VCkG)@LDCFfrT3GW$z38_wH;jyLK}Q#d)*-izuAv!r z${m{7L+XZpP!$5H-X3BGbO&8qhX#+$RX@x1Ld> zpq(!CgC3;=k)t}5d;{*rZoE?Y#fDQVXfjkPzm;LMY9XCGaWK6a)H7GFk|zf%)`7Zm z@L3-^atb=)1oy4iLM&ciy;fYjs@<%vEU32@h+NcVypGlv$nA~zNgy<3?zr&`K-WDx z4ITYkBL1fNB?sTMr^u2P7FR39($%tSb1$aDw)^koQ|jpSr&3%jR@?;(ESTCWmgqbH z77A7%h3m;T0lIJ!?T4;#^^SV;S^-sbec=W|>K(mUR+iWA04}Z}-WY7J+?(DH-WdSz z?*qWw--In*A1F@`d|~Tx@C~e^)2CSYd^HZ%Apv~wqUP+G&E)r!qa3VqxtZjzrerje z{O~lvGs*YAphz5-xH0!x>IX@l3s=8fYD!&ceX%9B^u1(D+~ZnWE7#Ie$5Q<5{;vhN z=I11PV{X0{NlmAY+=|J$H?lVhwRQ3xPaRp0$=CWSw3=wiP%nniuk(%6#9Dk_t@Tbj z*NN0bY>m<$w>R2SLAp-flc}SzQckzN-uhZ3->KB(o%ohTkd1(xk=y|I&AH!?{SW|$ zoduU{O{43r<9i7g$<|l)Cig~?e>{Urt&^TW??CdmUy`cbIfTnX%NH1~Lxsh;>*GIi zE9|Lh^l9ZrB5k;@>zp~2|8a7R^LIL&dM&@*+-*EqLRgYhe5t&-OW*SoN3K;GkD8nJ z{nSJWGVW~qiKEx@b!*$+^;458`7Jp8!Mqpbg;w6V^w%RlfmR}y!ZJZc<3YnglVM}7 zh$k+cpZKY(sVIfVKr=b++@;y0AG)fkg7Se@fx>_uz)gmG2e$=sBtOc2Hkn9sDezgz z;&Ja&l!8zWLK1{Z5UN3_1)&~XNrx~Zc?;8*8dTpE5AHf@C!2OY5v`LLE zI~&yMCs22aL^I0KggWh2+_WD&gr_Lb=rJ$7Q@0w+jk{UYoy1;Oa~p!2Dc8;v91#+{ z`p#*((wzbKXVAPFd|~Cj%Ub5Xy_*Z)DP|titz7646D_C?RWR_E(IYJ)IOoJW)ubb` z9@Au3$?(PwDj9epdBTS8BfHupgGvUkPW^7iwFzgj#7pb83GO*DZTiyUf&C0#;0`X? zf6oGh;@b4IGuNw~7b1v@G4KXHPBUIM(0|ar{#@Y;(>cGgwx0Iq3|*z#^}(?5a)mEw zz0QViPrh)$s2f~a0*_)*gMSMD2K<`|J)tDDgp?qVQsG~Re>biq+>`|WGRKYVzV)Xm z?ihE(bG6HA6t!b8N5NyV?4~v5de>! z`pJB=J+df{91?_l_du$PnTBcZJfwAVH|IE#^Ko0;@MI$5iHic?MC3^p6&K`rinN+5 zt%wa2mDZFGCM`HSf-|G6=@DT?lt5FVN2F$8U1_JFIZgT&|i_nj-; z_<#Na;rkpvdJMu(IR5q+$9=$Y{QX4;uW z;Ufq+?#Mq+cw&2+p@m}msZeY`6^b3C0N$||0crrj*qRXUgK5OFWU=1DOj&61J|ooho};+SHaV?Pi+UXR{Gbd z-AtB{!V+EfiCBEa7k)60T|ULQ7{j>D99EtKIhG9Rw9EYeW8HoZ>z2Ka^&CjehUwsN zs>uBRng4$b(U1B6_mdwFeT1?KpWS7VVaPCi6&$(y^{{vU-P!-kk^R5?-1qZ@os4$q=9^Xcc^G=b zEaX0in!xz~FGVr_FZusv#{X|02f+CM{;3K3F(e}l?SnHx(~SQ=n0p#Qmht~<9ja^> zSv#c2GXDS5kLD;a{=Yw;MMhOXCLhF-XZ-(R&U{%o_^i+P|NZ9~#1h!U$;~~lf${&J zcBVlrd;|Iajs5ulpECY``t&<|ND;rKk4}YV+;KMt>?=B_bJw$Gj;~?|Km>6 zQDqb{?8@`y|7W`R|Bxc~0#|CPx8pFX$!|9=7G CK(c)R literal 0 HcmV?d00001 diff --git a/data.trace.db b/data.trace.db new file mode 100644 index 0000000..d83d3b0 --- /dev/null +++ b/data.trace.db @@ -0,0 +1,449 @@ +2024-04-18 18:25:59.368842+04:00 jdbc[13]: exception +org.h2.jdbc.JdbcSQLSyntaxErrorException: Таблица "USERSREVIEWS" не найдена +Table "USERSREVIEWS" not found; SQL statement: +SELECT * FROM USERSREVIEWS [42102-224] +2024-04-18 18:26:39.326881+04:00 jdbc[13]: exception +org.h2.jdbc.JdbcSQLSyntaxErrorException: Столбец "USERS.USER_ID" не найден +Column "USERS.USER_ID" not found; SQL statement: +SELECT * FROM reviews join users on users.user_id [42122-224] + at org.h2.message.DbException.getJdbcSQLException(DbException.java:514) + at org.h2.message.DbException.getJdbcSQLException(DbException.java:489) + at org.h2.message.DbException.get(DbException.java:223) + at org.h2.message.DbException.get(DbException.java:199) + at org.h2.expression.ExpressionColumn.getColumnException(ExpressionColumn.java:244) + at org.h2.expression.ExpressionColumn.optimizeOther(ExpressionColumn.java:226) + at org.h2.expression.ExpressionColumn.optimize(ExpressionColumn.java:213) + at org.h2.expression.Expression.optimizeCondition(Expression.java:148) + at org.h2.command.query.Select.prepareExpressions(Select.java:1177) + at org.h2.command.query.Query.prepare(Query.java:218) + at org.h2.command.Parser.prepareCommand(Parser.java:489) + at org.h2.engine.SessionLocal.prepareLocal(SessionLocal.java:639) + at org.h2.engine.SessionLocal.prepareCommand(SessionLocal.java:559) + at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1166) + at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:245) + at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:231) + at org.h2.server.web.WebApp.getResult(WebApp.java:1345) + at org.h2.server.web.WebApp.query(WebApp.java:1143) + at org.h2.server.web.WebApp.query(WebApp.java:1119) + at org.h2.server.web.WebApp.process(WebApp.java:245) + at org.h2.server.web.WebApp.processRequest(WebApp.java:177) + at org.h2.server.web.JakartaWebServlet.doGet(JakartaWebServlet.java:129) + at org.h2.server.web.JakartaWebServlet.doPost(JakartaWebServlet.java:166) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.base/java.lang.Thread.run(Thread.java:1583) +2024-04-18 18:31:18.587415+04:00 jdbc[13]: exception +org.h2.jdbc.JdbcSQLSyntaxErrorException: Столбец "R.USERS_ID" не найден +Column "R.USERS_ID" not found; SQL statement: +SELECT u.login as login, count(*) as count FROM reviews r join users u on u.id = r.users_id [42122-224] + at org.h2.message.DbException.getJdbcSQLException(DbException.java:514) + at org.h2.message.DbException.getJdbcSQLException(DbException.java:489) + at org.h2.message.DbException.get(DbException.java:223) + at org.h2.message.DbException.get(DbException.java:199) + at org.h2.expression.ExpressionColumn.getColumnException(ExpressionColumn.java:244) + at org.h2.expression.ExpressionColumn.optimizeOther(ExpressionColumn.java:226) + at org.h2.expression.ExpressionColumn.optimize(ExpressionColumn.java:213) + at org.h2.expression.condition.Comparison.optimize(Comparison.java:148) + at org.h2.expression.Expression.optimizeCondition(Expression.java:148) + at org.h2.command.query.Select.prepareExpressions(Select.java:1177) + at org.h2.command.query.Query.prepare(Query.java:218) + at org.h2.command.Parser.prepareCommand(Parser.java:489) + at org.h2.engine.SessionLocal.prepareLocal(SessionLocal.java:639) + at org.h2.engine.SessionLocal.prepareCommand(SessionLocal.java:559) + at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1166) + at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:245) + at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:231) + at org.h2.server.web.WebApp.getResult(WebApp.java:1345) + at org.h2.server.web.WebApp.query(WebApp.java:1143) + at org.h2.server.web.WebApp.query(WebApp.java:1119) + at org.h2.server.web.WebApp.process(WebApp.java:245) + at org.h2.server.web.WebApp.processRequest(WebApp.java:177) + at org.h2.server.web.JakartaWebServlet.doGet(JakartaWebServlet.java:129) + at org.h2.server.web.JakartaWebServlet.doPost(JakartaWebServlet.java:166) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.base/java.lang.Thread.run(Thread.java:1583) +2024-04-18 18:31:26.826213+04:00 jdbc[13]: exception +org.h2.jdbc.JdbcSQLSyntaxErrorException: Столбец "U.LOGIN" должен быть в предложении GROUP BY +Column "U.LOGIN" must be in the GROUP BY list; SQL statement: +SELECT u.login as login, count(*) as count FROM reviews r join users u on u.id = r.user_id [90016-224] + at org.h2.message.DbException.getJdbcSQLException(DbException.java:644) + at org.h2.message.DbException.getJdbcSQLException(DbException.java:489) + at org.h2.message.DbException.get(DbException.java:223) + at org.h2.message.DbException.get(DbException.java:199) + at org.h2.expression.ExpressionColumn.updateAggregate(ExpressionColumn.java:266) + at org.h2.expression.Alias.updateAggregate(Alias.java:74) + at org.h2.command.query.Select.updateAgg(Select.java:539) + at org.h2.command.query.Select.gatherGroup(Select.java:522) + at org.h2.command.query.Select.queryGroup(Select.java:488) + at org.h2.command.query.Select.queryWithoutCache(Select.java:828) + at org.h2.command.query.Query.queryWithoutCacheLazyCheck(Query.java:197) + at org.h2.command.query.Query.query(Query.java:520) + at org.h2.command.query.Query.query(Query.java:483) + at org.h2.command.CommandContainer.query(CommandContainer.java:252) + at org.h2.command.Command.executeQuery(Command.java:192) + at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:257) + at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:231) + at org.h2.server.web.WebApp.getResult(WebApp.java:1345) + at org.h2.server.web.WebApp.query(WebApp.java:1143) + at org.h2.server.web.WebApp.query(WebApp.java:1119) + at org.h2.server.web.WebApp.process(WebApp.java:245) + at org.h2.server.web.WebApp.processRequest(WebApp.java:177) + at org.h2.server.web.JakartaWebServlet.doGet(JakartaWebServlet.java:129) + at org.h2.server.web.JakartaWebServlet.doPost(JakartaWebServlet.java:166) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.base/java.lang.Thread.run(Thread.java:1583) +2024-04-18 18:31:28.088309+04:00 jdbc[13]: exception +org.h2.jdbc.JdbcSQLSyntaxErrorException: Столбец "U.LOGIN" должен быть в предложении GROUP BY +Column "U.LOGIN" must be in the GROUP BY list; SQL statement: +SELECT u.login as login, count(*) as count FROM reviews r join users u on u.id = r.user_id [90016-224] + at org.h2.message.DbException.getJdbcSQLException(DbException.java:644) + at org.h2.message.DbException.getJdbcSQLException(DbException.java:489) + at org.h2.message.DbException.get(DbException.java:223) + at org.h2.message.DbException.get(DbException.java:199) + at org.h2.expression.ExpressionColumn.updateAggregate(ExpressionColumn.java:266) + at org.h2.expression.Alias.updateAggregate(Alias.java:74) + at org.h2.command.query.Select.updateAgg(Select.java:539) + at org.h2.command.query.Select.gatherGroup(Select.java:522) + at org.h2.command.query.Select.queryGroup(Select.java:488) + at org.h2.command.query.Select.queryWithoutCache(Select.java:828) + at org.h2.command.query.Query.queryWithoutCacheLazyCheck(Query.java:197) + at org.h2.command.query.Query.query(Query.java:520) + at org.h2.command.query.Query.query(Query.java:483) + at org.h2.command.CommandContainer.query(CommandContainer.java:252) + at org.h2.command.Command.executeQuery(Command.java:192) + at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:257) + at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:231) + at org.h2.server.web.WebApp.getResult(WebApp.java:1345) + at org.h2.server.web.WebApp.query(WebApp.java:1143) + at org.h2.server.web.WebApp.query(WebApp.java:1119) + at org.h2.server.web.WebApp.process(WebApp.java:245) + at org.h2.server.web.WebApp.processRequest(WebApp.java:177) + at org.h2.server.web.JakartaWebServlet.doGet(JakartaWebServlet.java:129) + at org.h2.server.web.JakartaWebServlet.doPost(JakartaWebServlet.java:166) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.base/java.lang.Thread.run(Thread.java:1583) +2024-04-18 18:35:53.107821+04:00 jdbc[13]: exception +org.h2.jdbc.JdbcSQLSyntaxErrorException: Синтаксическая ошибка в выражении SQL "SELECT u.login as login, count(*) as count FROM reviews r join users u on u.id = r.user_id group by login order by count [*]dsc" +Syntax error in SQL statement "SELECT u.login as login, count(*) as count FROM reviews r join users u on u.id = r.user_id group by login order by count [*]dsc"; SQL statement: +SELECT u.login as login, count(*) as count FROM reviews r join users u on u.id = r.user_id group by login order by count dsc [42000-224] +2024-04-18 18:36:21.300704+04:00 jdbc[13]: exception +org.h2.jdbc.JdbcSQLSyntaxErrorException: Синтаксическая ошибка в выражении SQL "SELECT u.login as login, count(*) as count FROM reviews r join users u on u.id = r.user_id group by login order by count [*]DSC" +Syntax error in SQL statement "SELECT u.login as login, count(*) as count FROM reviews r join users u on u.id = r.user_id group by login order by count [*]DSC"; SQL statement: +SELECT u.login as login, count(*) as count FROM reviews r join users u on u.id = r.user_id group by login order by count DSC [42000-224] +2024-04-18 18:36:41.364562+04:00 jdbc[13]: exception +org.h2.jdbc.JdbcSQLSyntaxErrorException: Синтаксическая ошибка в выражении SQL "SELECT u.login as login, count(*) as count FROM reviews r join users u on u.id = r.user_id group by login order by count [*]DES" +Syntax error in SQL statement "SELECT u.login as login, count(*) as count FROM reviews r join users u on u.id = r.user_id group by login order by count [*]DES"; SQL statement: +SELECT u.login as login, count(*) as count FROM reviews r join users u on u.id = r.user_id group by login order by count DES [42000-224] +2024-04-18 18:41:46.400938+04:00 database: wrong user or password; user: "SA" +org.h2.message.DbException: Неверное имя пользователя или пароль +Wrong user name or password [28000-224] + at org.h2.message.DbException.get(DbException.java:223) + at org.h2.message.DbException.get(DbException.java:199) + at org.h2.message.DbException.get(DbException.java:188) + at org.h2.engine.Engine.openSession(Engine.java:154) + at org.h2.engine.Engine.openSession(Engine.java:222) + at org.h2.engine.Engine.createSession(Engine.java:201) + at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:343) + at org.h2.jdbc.JdbcConnection.(JdbcConnection.java:125) + at org.h2.util.JdbcUtils.getConnection(JdbcUtils.java:288) + at org.h2.server.web.WebServer.getConnection(WebServer.java:811) + at org.h2.server.web.WebApp.login(WebApp.java:1039) + at org.h2.server.web.WebApp.process(WebApp.java:227) + at org.h2.server.web.WebApp.processRequest(WebApp.java:177) + at org.h2.server.web.JakartaWebServlet.doGet(JakartaWebServlet.java:129) + at org.h2.server.web.JakartaWebServlet.doPost(JakartaWebServlet.java:166) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.base/java.lang.Thread.run(Thread.java:1583) +Caused by: org.h2.jdbc.JdbcSQLInvalidAuthorizationSpecException: Неверное имя пользователя или пароль +Wrong user name or password [28000-224] + at org.h2.message.DbException.getJdbcSQLException(DbException.java:522) + at org.h2.message.DbException.getJdbcSQLException(DbException.java:489) + ... 50 more +2024-04-18 18:42:06.702323+04:00 jdbc[13]: exception +org.h2.jdbc.JdbcSQLSyntaxErrorException: Столбец "U" не найден +Column "U" not found; SQL statement: +SELECT u as login, count(*) as count FROM reviews r join users u on u.id = r.user_id group by login [42122-224] + at org.h2.message.DbException.getJdbcSQLException(DbException.java:514) + at org.h2.message.DbException.getJdbcSQLException(DbException.java:489) + at org.h2.message.DbException.get(DbException.java:223) + at org.h2.message.DbException.get(DbException.java:199) + at org.h2.expression.ExpressionColumn.getColumnException(ExpressionColumn.java:244) + at org.h2.expression.ExpressionColumn.optimizeOther(ExpressionColumn.java:226) + at org.h2.expression.ExpressionColumn.optimize(ExpressionColumn.java:213) + at org.h2.expression.Alias.optimize(Alias.java:52) + at org.h2.command.query.Select.prepareExpressions(Select.java:1170) + at org.h2.command.query.Query.prepare(Query.java:218) + at org.h2.command.Parser.prepareCommand(Parser.java:489) + at org.h2.engine.SessionLocal.prepareLocal(SessionLocal.java:639) + at org.h2.engine.SessionLocal.prepareCommand(SessionLocal.java:559) + at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1166) + at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:245) + at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:231) + at org.h2.server.web.WebApp.getResult(WebApp.java:1345) + at org.h2.server.web.WebApp.query(WebApp.java:1143) + at org.h2.server.web.WebApp.query(WebApp.java:1119) + at org.h2.server.web.WebApp.process(WebApp.java:245) + at org.h2.server.web.WebApp.processRequest(WebApp.java:177) + at org.h2.server.web.JakartaWebServlet.doGet(JakartaWebServlet.java:129) + at org.h2.server.web.JakartaWebServlet.doPost(JakartaWebServlet.java:166) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.base/java.lang.Thread.run(Thread.java:1583) +2024-04-18 18:43:02.191025+04:00 jdbc[13]: exception +org.h2.jdbc.JdbcSQLSyntaxErrorException: Столбец "U" не найден +Column "U" not found; SQL statement: +SELECT u as login, count(*) as count FROM reviews r join users u on u.id = r.user_id group by login [42122-224] + at org.h2.message.DbException.getJdbcSQLException(DbException.java:514) + at org.h2.message.DbException.getJdbcSQLException(DbException.java:489) + at org.h2.message.DbException.get(DbException.java:223) + at org.h2.message.DbException.get(DbException.java:199) + at org.h2.expression.ExpressionColumn.getColumnException(ExpressionColumn.java:244) + at org.h2.expression.ExpressionColumn.optimizeOther(ExpressionColumn.java:226) + at org.h2.expression.ExpressionColumn.optimize(ExpressionColumn.java:213) + at org.h2.expression.Alias.optimize(Alias.java:52) + at org.h2.command.query.Select.prepareExpressions(Select.java:1170) + at org.h2.command.query.Query.prepare(Query.java:218) + at org.h2.command.Parser.prepareCommand(Parser.java:489) + at org.h2.engine.SessionLocal.prepareLocal(SessionLocal.java:639) + at org.h2.engine.SessionLocal.prepareCommand(SessionLocal.java:559) + at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1166) + at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:245) + at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:231) + at org.h2.server.web.WebApp.getResult(WebApp.java:1345) + at org.h2.server.web.WebApp.query(WebApp.java:1143) + at org.h2.server.web.WebApp.query(WebApp.java:1119) + at org.h2.server.web.WebApp.process(WebApp.java:245) + at org.h2.server.web.WebApp.processRequest(WebApp.java:177) + at org.h2.server.web.JakartaWebServlet.doGet(JakartaWebServlet.java:129) + at org.h2.server.web.JakartaWebServlet.doPost(JakartaWebServlet.java:166) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.base/java.lang.Thread.run(Thread.java:1583) diff --git a/src/main/java/ip_2/lab1/Lab1Application.java b/src/main/java/ip_2/lab1/Lab1Application.java index a95f738..885c01b 100644 --- a/src/main/java/ip_2/lab1/Lab1Application.java +++ b/src/main/java/ip_2/lab1/Lab1Application.java @@ -2,8 +2,13 @@ package ip_2.lab1; import ip_2.lab1.items.model.ItemEntity; import ip_2.lab1.items.service.ItemService; +import ip_2.lab1.reviews.model.ReviewEntity; +import ip_2.lab1.reviews.service.ReviewService; import ip_2.lab1.types.model.TypeEntity; import ip_2.lab1.types.service.TypeService; +import ip_2.lab1.users.model.UserEntity; +import ip_2.lab1.users.service.UserService; +import org.h2.engine.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.CommandLineRunner; @@ -18,10 +23,14 @@ public class Lab1Application implements CommandLineRunner { private final TypeService typeService; private final ItemService itemService; + private final UserService userService; + private final ReviewService reviewService; - public Lab1Application(TypeService typeService, ItemService itemService) { + public Lab1Application(TypeService typeService, ItemService itemService, UserService userService, ReviewService reviewService) { this.typeService = typeService; this.itemService = itemService; + this.userService = userService; + this.reviewService = reviewService; } public static void main(String[] args) { @@ -32,18 +41,36 @@ public class Lab1Application implements CommandLineRunner { public void run(String... args) throws Exception { if (args.length > 0 && Objects.equals("--populate", args[0])) { log.info("Create default types values"); - final var type1 = typeService.create(new TypeEntity(null, "Асфальт", 2000)); - final var type2 = typeService.create(new TypeEntity(null, "Грунт", 3000)); - final var type3 = typeService.create(new TypeEntity(null, "Асфальт + грунт", 3500)); + final var type1 = typeService.create(new TypeEntity("Асфальт", 2000)); + final var type2 = typeService.create(new TypeEntity("Грунт", 3000)); + final var type3 = typeService.create(new TypeEntity("Асфальт + грунт", 3500)); - log.info("Create default items values"); - itemService.create(new ItemEntity(null, type1, 49999, 20)); - itemService.create(new ItemEntity(null, type1, 129999, 3)); - itemService.create(new ItemEntity(null, type2, 15450, 30)); - itemService.create(new ItemEntity(null, type2, 69900, 10)); - itemService.create(new ItemEntity(null, type2, 150000, 6)); - itemService.create(new ItemEntity(null, type3, 75000, 6)); - itemService.create(new ItemEntity(null, type3, 67800, 3)); + log.info("Create items"); + final var item1 = itemService.create(new ItemEntity(type1, 1700, 5)); + final var item2 = itemService.create(new ItemEntity(type2, 2700, 5)); + final var item3 = itemService.create(new ItemEntity(type3, 3200, 5)); + + log.info("Create users"); + final var user1 = userService.create(new UserEntity("Artyom", "1234")); + final var user2 = userService.create(new UserEntity("Niyaz", "1234")); + final var user3 = userService.create(new UserEntity("Rostik", "1234")); + final var user4 = userService.create(new UserEntity("Artur", "1234")); + final var user5 = userService.create(new UserEntity("Andrey", "1234")); + final var user6 = userService.create(new UserEntity("Alionchik", "1234")); + + + log.info("Create reviews"); + final var review1 = reviewService.create(new ReviewEntity(user1, "Кайфарики")); + final var review2 = reviewService.create(new ReviewEntity(user2, "Кайфарики кайфецкие")); + final var review3 = reviewService.create(new ReviewEntity(user3, "Кайфарики турецкие")); + final var review4 = reviewService.create(new ReviewEntity(user3, "Кайфарики масдавские")); + final var review5 = reviewService.create(new ReviewEntity(user4, "Кайфарики минские")); + final var review7 = reviewService.create(new ReviewEntity(user4, "Кайфарики грузинские")); + final var review8 = reviewService.create(new ReviewEntity(user5, "Кайфарики японские")); + final var review9 = reviewService.create(new ReviewEntity(user6, "Кайфарики македонские")); + + + log.info("Creation finished"); } } } diff --git a/src/main/java/ip_2/lab1/core/api/PageDto.java b/src/main/java/ip_2/lab1/core/api/PageDto.java new file mode 100644 index 0000000..1e9c0c6 --- /dev/null +++ b/src/main/java/ip_2/lab1/core/api/PageDto.java @@ -0,0 +1,97 @@ +package ip_2.lab1.core.api; + +import java.util.ArrayList; +import java.util.List; + +public class PageDto { + private List items = new ArrayList<>(); + private int itemsCount; + private int currentPage; + private int currentSize; + private int totalPages; + private long totalItems; + private boolean isFirst; + private boolean isLast; + private boolean hasNext; + private boolean hasPrevious; + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + + public int getItemsCount() { + return itemsCount; + } + + public void setItemsCount(int itemsCount) { + this.itemsCount = itemsCount; + } + + public int getCurrentPage() { + return currentPage; + } + + public void setCurrentPage(int currentPage) { + this.currentPage = currentPage; + } + + public int getCurrentSize() { + return currentSize; + } + + public void setCurrentSize(int currentSize) { + this.currentSize = currentSize; + } + + public int getTotalPages() { + return totalPages; + } + + public void setTotalPages(int totalPages) { + this.totalPages = totalPages; + } + + public long getTotalItems() { + return totalItems; + } + + public void setTotalItems(long totalItems) { + this.totalItems = totalItems; + } + + public boolean isFirst() { + return isFirst; + } + + public void setFirst(boolean isFirst) { + this.isFirst = isFirst; + } + + public boolean isLast() { + return isLast; + } + + public void setLast(boolean isLast) { + this.isLast = isLast; + } + + public boolean isHasNext() { + return hasNext; + } + + public void setHasNext(boolean hasNext) { + this.hasNext = hasNext; + } + + public boolean isHasPrevious() { + return hasPrevious; + } + + public void setHasPrevious(boolean hasPrevious) { + this.hasPrevious = hasPrevious; + } +} diff --git a/src/main/java/ip_2/lab1/core/api/PageDtoMapper.java b/src/main/java/ip_2/lab1/core/api/PageDtoMapper.java new file mode 100644 index 0000000..722b28a --- /dev/null +++ b/src/main/java/ip_2/lab1/core/api/PageDtoMapper.java @@ -0,0 +1,25 @@ +package ip_2.lab1.core.api; + +import org.springframework.data.domain.Page; + +import java.util.function.Function; + +public class PageDtoMapper { + private PageDtoMapper() { + } + + public static PageDto toDto(Page page, Function mapper) { + final PageDto dto = new PageDto<>(); + dto.setItems(page.getContent().stream().map(mapper::apply).toList()); + dto.setItemsCount(page.getNumberOfElements()); + dto.setCurrentPage(page.getNumber()); + dto.setCurrentSize(page.getSize()); + dto.setTotalPages(page.getTotalPages()); + dto.setTotalItems(page.getTotalElements()); + dto.setFirst(page.isFirst()); + dto.setLast(page.isLast()); + dto.setHasNext(page.hasNext()); + dto.setHasPrevious(page.hasPrevious()); + return dto; + } +} diff --git a/src/main/java/ip_2/lab1/core/configuration/Constants.java b/src/main/java/ip_2/lab1/core/configuration/Constants.java index 8de88f6..0015b26 100644 --- a/src/main/java/ip_2/lab1/core/configuration/Constants.java +++ b/src/main/java/ip_2/lab1/core/configuration/Constants.java @@ -1,6 +1,8 @@ package ip_2.lab1.core.configuration; public class Constants { + public static final String SEQUENCE_NAME = "hibernate_sequence"; + public static final String API_URL = "/api/1.0"; private Constants(){ diff --git a/src/main/java/ip_2/lab1/core/error/NotFoundException.java b/src/main/java/ip_2/lab1/core/error/NotFoundException.java index aa91d0d..68a0134 100644 --- a/src/main/java/ip_2/lab1/core/error/NotFoundException.java +++ b/src/main/java/ip_2/lab1/core/error/NotFoundException.java @@ -1,7 +1,7 @@ package ip_2.lab1.core.error; public class NotFoundException extends RuntimeException{ - public NotFoundException(Long id) { - super(String.format("Entity with id [%s] is not found or not exists", id)); + public NotFoundException(Class clazz, Long id) { + super(String.format("%s with id [%s] is not found or not exists", clazz.getSimpleName(), id)); } } diff --git a/src/main/java/ip_2/lab1/core/model/BaseEntity.java b/src/main/java/ip_2/lab1/core/model/BaseEntity.java index b255327..f1a06bf 100644 --- a/src/main/java/ip_2/lab1/core/model/BaseEntity.java +++ b/src/main/java/ip_2/lab1/core/model/BaseEntity.java @@ -1,15 +1,18 @@ package ip_2.lab1.core.model; import com.fasterxml.jackson.databind.ser.Serializers; +import ip_2.lab1.core.configuration.Constants; +import jakarta.persistence.*; +@MappedSuperclass public abstract class BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = Constants.SEQUENCE_NAME) + @SequenceGenerator(name = Constants.SEQUENCE_NAME, sequenceName = Constants.SEQUENCE_NAME, allocationSize = 1) protected Long id; protected BaseEntity(){ } - protected BaseEntity(Long id){ - this.id = id; - } public Long getId(){ return id; diff --git a/src/main/java/ip_2/lab1/core/repository/CommonRepository.java b/src/main/java/ip_2/lab1/core/repository/CommonRepository.java deleted file mode 100644 index b08721d..0000000 --- a/src/main/java/ip_2/lab1/core/repository/CommonRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package ip_2.lab1.core.repository; - -import java.util.List; - -public interface CommonRepository { - List getAll(); - - E get(T id); - E create (E entity); - E update (E entity); - E delete (E entity); - void deleteAll(); -} diff --git a/src/main/java/ip_2/lab1/core/repository/MapRepository.java b/src/main/java/ip_2/lab1/core/repository/MapRepository.java deleted file mode 100644 index e9e2fd6..0000000 --- a/src/main/java/ip_2/lab1/core/repository/MapRepository.java +++ /dev/null @@ -1,55 +0,0 @@ -package ip_2.lab1.core.repository; - -import ip_2.lab1.core.model.BaseEntity; - -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -public abstract class MapRepository implements CommonRepository { - private final Map entities = new TreeMap<>(); - private Long lastId = 0L; - - protected MapRepository() { - } - - @Override - public List getAll() { - return entities.values().stream().toList(); - } - - @Override - public E get(Long id) { - return entities.get(id); - } - - @Override - public E create(E entity) { - lastId++; - entity.setId(lastId); - entities.put(lastId, entity); - return entity; - } - - @Override - public E update (E entity) { - if (get(entity.getId()) == null) - return null; - entities.put(entity.getId(), entity); - return entity; - } - - @Override - public E delete (E entity) { - if (get(entity.getId()) == null) - return null; - entities.remove(entity.getId()); - return entity; - } - - @Override - public void deleteAll() { - lastId = 0L; - entities.clear(); - } -} diff --git a/src/main/java/ip_2/lab1/items/api/ItemController.java b/src/main/java/ip_2/lab1/items/api/ItemController.java index bf8f6a9..990504c 100644 --- a/src/main/java/ip_2/lab1/items/api/ItemController.java +++ b/src/main/java/ip_2/lab1/items/api/ItemController.java @@ -2,6 +2,7 @@ package ip_2.lab1.items.api; import ip_2.lab1.core.configuration.Constants; import ip_2.lab1.items.model.ItemEntity; +import ip_2.lab1.items.model.ItemGrouped; import ip_2.lab1.items.service.ItemService; import ip_2.lab1.types.service.TypeService; import jakarta.validation.Valid; @@ -36,6 +37,10 @@ public class ItemController { entity.setType(typeService.get(dto.getTypeId())); return entity; } + private ItemGroupedDto toGroupedDto(ItemGrouped entity) { + return modelMapper.map(entity, ItemGroupedDto.class); + } + @GetMapping public List getAll(@RequestParam(name = "typeId", defaultValue = "0") Long typeId) { @@ -48,8 +53,9 @@ public class ItemController { } @PostMapping - public ItemDto create(@RequestBody ItemDto dto) { - return toDto(itemService.create(toEntity(dto))); + public ItemDto create( + @RequestBody ItemDto dto) { + return toDto(itemService.create( toEntity(dto))); } @PutMapping("/{id}") @@ -61,4 +67,11 @@ public class ItemController { public ItemDto delete(@PathVariable(name = "id") Long id) { return toDto(itemService.delete(id)); } + + @GetMapping("/total") + public List getTotalPrice() { + return itemService.getTotal().stream() + .map(this::toGroupedDto) + .toList(); + } } diff --git a/src/main/java/ip_2/lab1/items/api/ItemDto.java b/src/main/java/ip_2/lab1/items/api/ItemDto.java index 8376abc..2ffdd50 100644 --- a/src/main/java/ip_2/lab1/items/api/ItemDto.java +++ b/src/main/java/ip_2/lab1/items/api/ItemDto.java @@ -9,6 +9,7 @@ import jakarta.validation.constraints.NotNull; import java.util.Objects; public class ItemDto { + @JsonProperty(access = JsonProperty.Access.READ_ONLY) private Long id; @NotNull @Min(1) @@ -22,7 +23,6 @@ public class ItemDto { private Double benefit; - @JsonProperty(access = JsonProperty.Access.READ_ONLY) public Long getId() { return id; } diff --git a/src/main/java/ip_2/lab1/items/api/ItemGroupedDto.java b/src/main/java/ip_2/lab1/items/api/ItemGroupedDto.java new file mode 100644 index 0000000..8a6380b --- /dev/null +++ b/src/main/java/ip_2/lab1/items/api/ItemGroupedDto.java @@ -0,0 +1,22 @@ +package ip_2.lab1.items.api; + +public class ItemGroupedDto { + private Long typeId; + private Integer totalPrice; + + public Long getTypeId() { + return typeId; + } + + public void setTypeId(Long typeId) { + this.typeId = typeId; + } + + public Integer getTotalPrice() { + return totalPrice; + } + + public void setTotalPrice(Integer totalPrice) { + this.totalPrice = totalPrice; + } +} diff --git a/src/main/java/ip_2/lab1/items/model/ItemEntity.java b/src/main/java/ip_2/lab1/items/model/ItemEntity.java index 10991d9..e4fb856 100644 --- a/src/main/java/ip_2/lab1/items/model/ItemEntity.java +++ b/src/main/java/ip_2/lab1/items/model/ItemEntity.java @@ -3,20 +3,25 @@ package ip_2.lab1.items.model; import io.swagger.v3.oas.models.security.SecurityScheme; import ip_2.lab1.core.model.BaseEntity; import ip_2.lab1.types.model.TypeEntity; +import jakarta.persistence.*; import java.util.Objects; +@Entity +@Table(name = "items") public class ItemEntity extends BaseEntity { + @ManyToOne + @JoinColumn(name = "typeId", nullable = false) private TypeEntity type; + @Column(nullable = false) private Integer price; + @Column(nullable = false) private Integer count; public ItemEntity() { - super(); } - public ItemEntity(Long id, TypeEntity type, Integer price, Integer count) { - super(id); + public ItemEntity(TypeEntity type, Integer price, Integer count) { this.type = type; this.price = price; this.count = count; diff --git a/src/main/java/ip_2/lab1/items/model/ItemGrouped.java b/src/main/java/ip_2/lab1/items/model/ItemGrouped.java new file mode 100644 index 0000000..1d549be --- /dev/null +++ b/src/main/java/ip_2/lab1/items/model/ItemGrouped.java @@ -0,0 +1,8 @@ +package ip_2.lab1.items.model; + +import ip_2.lab1.types.model.TypeEntity; + +public interface ItemGrouped { + TypeEntity getType(); + int getTotalPrice(); +} diff --git a/src/main/java/ip_2/lab1/items/repository/ItemRepository.java b/src/main/java/ip_2/lab1/items/repository/ItemRepository.java index 4b5eab3..7090433 100644 --- a/src/main/java/ip_2/lab1/items/repository/ItemRepository.java +++ b/src/main/java/ip_2/lab1/items/repository/ItemRepository.java @@ -1,9 +1,17 @@ package ip_2.lab1.items.repository; -import ip_2.lab1.core.repository.MapRepository; import ip_2.lab1.items.model.ItemEntity; -import org.springframework.stereotype.Repository; +import ip_2.lab1.items.model.ItemGrouped; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import java.util.List; -@Repository -public class ItemRepository extends MapRepository { -} +public interface ItemRepository extends CrudRepository { + List findByTypeId(long typeId); + void deleteAllByTypeId(Long typeId); + + @Query("select t as type, coalesce(sum(i.price * i.count), 0) as totalPrice " + + "from TypeEntity t left join ItemEntity i on i.type = t " + + "group by t order by t.id") + List getItemsTotalByType(); +} \ No newline at end of file diff --git a/src/main/java/ip_2/lab1/items/service/ItemService.java b/src/main/java/ip_2/lab1/items/service/ItemService.java index 577f302..222e0e8 100644 --- a/src/main/java/ip_2/lab1/items/service/ItemService.java +++ b/src/main/java/ip_2/lab1/items/service/ItemService.java @@ -2,12 +2,17 @@ package ip_2.lab1.items.service; import ip_2.lab1.core.error.NotFoundException; import ip_2.lab1.items.model.ItemEntity; +import ip_2.lab1.items.model.ItemGrouped; import ip_2.lab1.items.repository.ItemRepository; +import ip_2.lab1.types.model.TypeEntity; +import ip_2.lab1.types.service.TypeService; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.stream.StreamSupport; @Service public class ItemService { @@ -17,33 +22,47 @@ public class ItemService { this.repository = repository; } - public List getAll(Long typeId) { - if (Objects.equals(typeId, 0L)) { - return repository.getAll(); + @Transactional(readOnly = true) + public List getAll(long typeId) { + if (typeId <= 0L) { + return StreamSupport.stream(repository.findAll().spliterator(), false).toList(); + } else { + return repository.findByTypeId(typeId); } - return repository.getAll().stream() - .filter(item -> item.getType().getId().equals(typeId)).toList(); } - public ItemEntity get(Long id) { - return Optional.ofNullable(repository.get(id)) - .orElseThrow(() -> new NotFoundException(id)); + @Transactional(readOnly = true) + public ItemEntity get(long id) { + return repository.findById(id) + .orElseThrow(() -> new NotFoundException(ItemEntity.class, id)); } + @Transactional public ItemEntity create(ItemEntity entity) { - return repository.create(entity); + if (entity == null) { + throw new IllegalArgumentException("Entity is null"); + } + return repository.save(entity); } - public ItemEntity update(Long id, ItemEntity entity) { + @Transactional + public ItemEntity update(long id, ItemEntity entity) { final ItemEntity existsEntity = get(id); existsEntity.setType(entity.getType()); existsEntity.setPrice(entity.getPrice()); existsEntity.setCount(entity.getCount()); - return repository.update(existsEntity); + return repository.save(existsEntity); } - public ItemEntity delete(Long id) { + @Transactional + public ItemEntity delete(long id) { final ItemEntity existsEntity = get(id); - return repository.delete(existsEntity); + repository.delete(existsEntity); + return existsEntity; + } + + @Transactional(readOnly = true) + public List getTotal() { + return repository.getItemsTotalByType(); } } diff --git a/src/main/java/ip_2/lab1/reviews/api/ReviewController.java b/src/main/java/ip_2/lab1/reviews/api/ReviewController.java index ae30c33..4763b3a 100644 --- a/src/main/java/ip_2/lab1/reviews/api/ReviewController.java +++ b/src/main/java/ip_2/lab1/reviews/api/ReviewController.java @@ -1,24 +1,38 @@ package ip_2.lab1.reviews.api; +import ip_2.lab1.core.api.PageDto; +import ip_2.lab1.core.api.PageDtoMapper; import ip_2.lab1.core.configuration.Constants; +import ip_2.lab1.items.api.ItemGroupedDto; +import ip_2.lab1.items.model.ItemGrouped; import ip_2.lab1.reviews.model.ReviewEntity; +import ip_2.lab1.reviews.model.ReviewGrouped; +import ip_2.lab1.reviews.repository.ReviewRepository; import ip_2.lab1.reviews.service.ReviewService; -import ip_2.lab1.types.api.TypeDto; -import ip_2.lab1.types.model.TypeEntity; -import ip_2.lab1.types.service.TypeService; +import ip_2.lab1.users.service.UserService; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; import org.modelmapper.ModelMapper; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.jaxb.SpringDataJaxb; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import java.util.List; +import java.util.stream.StreamSupport; @RestController @RequestMapping(Constants.API_URL + "/review") public class ReviewController { + private final UserService userService; private final ReviewService reviewService; + private final ReviewRepository reviewRepository; private final ModelMapper modelMapper; - public ReviewController(ReviewService reviewService, ModelMapper modelMapper) { + public ReviewController(UserService userService, ReviewService reviewService, ReviewRepository reviewRepository, ModelMapper modelMapper) { + this.userService = userService; this.reviewService = reviewService; + this.reviewRepository = reviewRepository; this.modelMapper = modelMapper; } @@ -26,12 +40,19 @@ public class ReviewController { return modelMapper.map(entity, ReviewDto.class); } private ReviewEntity toEntity(ReviewDto dto) { - return modelMapper.map(dto, ReviewEntity.class); + final ReviewEntity entity = modelMapper.map(dto, ReviewEntity.class); + entity.setUser(userService.getForReviewCreate(dto.getUserId())); + return entity; + } + private ReviewGroupedDto toGroupedDto(ReviewGrouped entity) { + return modelMapper.map(entity, ReviewGroupedDto.class); } @GetMapping - public List getAll() { - return reviewService.getAll().stream().map(this::toDto).toList(); + public PageDto getAll(@RequestParam(name = "userId", defaultValue = "0") Long userId, + @RequestParam(name = "page", defaultValue = "0") Integer page, + @RequestParam(name = "size", defaultValue = "20") Integer size) { + return PageDtoMapper.toDto(reviewService.getAll(userId, page, size), this::toDto); } @GetMapping("/{id}") @@ -53,4 +74,9 @@ public class ReviewController { public ReviewDto delete(@PathVariable(name = "id") Long id) { return toDto(reviewService.delete(id)); } + + @GetMapping("/count") + public List getReviewCount() { + return reviewService.getCount(0, 5).stream().map(this::toGroupedDto).toList(); + } } diff --git a/src/main/java/ip_2/lab1/reviews/api/ReviewDto.java b/src/main/java/ip_2/lab1/reviews/api/ReviewDto.java index 63e144a..de3f6a2 100644 --- a/src/main/java/ip_2/lab1/reviews/api/ReviewDto.java +++ b/src/main/java/ip_2/lab1/reviews/api/ReviewDto.java @@ -4,15 +4,18 @@ import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; public class ReviewDto { + @JsonProperty(access = JsonProperty.Access.READ_ONLY) private Long id; + @NotNull + @Min(1) + private Long userId; @NotBlank - private String name; - @NotBlank + @Size(min = 3, max = 300) private String text; - @JsonProperty(access = JsonProperty.Access.READ_ONLY) public Long getId() { return id; } @@ -20,11 +23,11 @@ public class ReviewDto { this.id = id; } - public String getName() { - return name; + public Long getUserId() { + return userId; } - public void setName(String name) { - this.name = name; + public void setUserId(Long userId) { + this.userId = userId; } public String getText() { return text; } diff --git a/src/main/java/ip_2/lab1/reviews/api/ReviewGroupedDto.java b/src/main/java/ip_2/lab1/reviews/api/ReviewGroupedDto.java new file mode 100644 index 0000000..585060e --- /dev/null +++ b/src/main/java/ip_2/lab1/reviews/api/ReviewGroupedDto.java @@ -0,0 +1,22 @@ +package ip_2.lab1.reviews.api; + +public class ReviewGroupedDto { + private String userLogin; + private Integer count; + + public Integer getCount() { + return count; + } + + public void setCount(Integer count) { + this.count = count; + } + + public String getUserLogin() { + return userLogin; + } + + public void setUserLogin(String userLogin) { + this.userLogin = userLogin; + } +} diff --git a/src/main/java/ip_2/lab1/reviews/model/ReviewEntity.java b/src/main/java/ip_2/lab1/reviews/model/ReviewEntity.java index 08b7866..4e10ad3 100644 --- a/src/main/java/ip_2/lab1/reviews/model/ReviewEntity.java +++ b/src/main/java/ip_2/lab1/reviews/model/ReviewEntity.java @@ -2,29 +2,36 @@ package ip_2.lab1.reviews.model; import ip_2.lab1.core.model.BaseEntity; import ip_2.lab1.types.model.TypeEntity; +import ip_2.lab1.users.model.UserEntity; +import jakarta.persistence.*; +import org.h2.engine.User; +import org.hibernate.annotations.Cascade; import java.util.Objects; +@Entity +@Table(name = "reviews") public class ReviewEntity extends BaseEntity { - private String name; + @ManyToOne + @JoinColumn(name = "userId", nullable = false) + private UserEntity user; + @Column(nullable = false, length = 300) private String text; + public ReviewEntity() { - super(); } - public ReviewEntity(Long id, String name, String text) { - super(id); - this.name = name; + public ReviewEntity(UserEntity user, String text) { + this.user = user; this.text = text; } - public String getName() { - return name; + public UserEntity getUser() { return user;} + public void setUser(UserEntity user) { + this.user = user; + if(!user.getReviews().contains(this)) + user.addReview(this); } - public void setName(String name) { - this.name = name; - } - public String getText() { return text; } @@ -34,7 +41,7 @@ public class ReviewEntity extends BaseEntity { @Override public int hashCode() { - return Objects.hash(id, name, text); + return Objects.hash(id, user, text); } @Override @@ -44,7 +51,7 @@ public class ReviewEntity extends BaseEntity { if (obj == null || getClass() != obj.getClass()) return false; final ReviewEntity other = (ReviewEntity) obj; - return Objects.equals(other.getId(), id) && Objects.equals(other.getName(), name) + return Objects.equals(other.getId(), id) && Objects.equals(other.getUser().getId(), user.getId()) && Objects.equals(other.getText(), text); } } diff --git a/src/main/java/ip_2/lab1/reviews/model/ReviewGrouped.java b/src/main/java/ip_2/lab1/reviews/model/ReviewGrouped.java new file mode 100644 index 0000000..3da9dc7 --- /dev/null +++ b/src/main/java/ip_2/lab1/reviews/model/ReviewGrouped.java @@ -0,0 +1,8 @@ +package ip_2.lab1.reviews.model; + +import ip_2.lab1.users.model.UserEntity; + +public interface ReviewGrouped { + UserEntity getUser(); + Integer getCount(); +} diff --git a/src/main/java/ip_2/lab1/reviews/repository/ReviewRepository.java b/src/main/java/ip_2/lab1/reviews/repository/ReviewRepository.java index b69ed32..b756da8 100644 --- a/src/main/java/ip_2/lab1/reviews/repository/ReviewRepository.java +++ b/src/main/java/ip_2/lab1/reviews/repository/ReviewRepository.java @@ -1,9 +1,22 @@ package ip_2.lab1.reviews.repository; -import ip_2.lab1.core.repository.MapRepository; import ip_2.lab1.reviews.model.ReviewEntity; -import org.springframework.stereotype.Repository; +import ip_2.lab1.reviews.model.ReviewGrouped; +import ip_2.lab1.users.model.UserEntity; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.PagingAndSortingRepository; + +import java.util.List; + +public interface ReviewRepository extends CrudRepository, PagingAndSortingRepository { + Page findByUserId(Long userId, Pageable pageable); + List findByUserId(Long userId); + void deleteAllByUserId(Long userId); + + @Query("SELECT u as user, count(*) as count FROM ReviewEntity r join UserEntity u on u = r.user group by user order by count DESC ") + Page getReviewCountByUsers(Pageable pageable); -@Repository -public class ReviewRepository extends MapRepository { } diff --git a/src/main/java/ip_2/lab1/reviews/service/ReviewService.java b/src/main/java/ip_2/lab1/reviews/service/ReviewService.java index 341042e..7b9db1e 100644 --- a/src/main/java/ip_2/lab1/reviews/service/ReviewService.java +++ b/src/main/java/ip_2/lab1/reviews/service/ReviewService.java @@ -1,44 +1,86 @@ package ip_2.lab1.reviews.service; import ip_2.lab1.core.error.NotFoundException; +import ip_2.lab1.items.model.ItemGrouped; import ip_2.lab1.reviews.model.ReviewEntity; +import ip_2.lab1.reviews.model.ReviewGrouped; import ip_2.lab1.reviews.repository.ReviewRepository; import ip_2.lab1.types.model.TypeEntity; import ip_2.lab1.types.repository.TypeRepository; +import ip_2.lab1.users.model.UserEntity; +import ip_2.lab1.users.service.UserService; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import org.antlr.v4.runtime.atn.SemanticContext; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.RequestParam; import java.util.List; import java.util.Optional; +import java.util.stream.StreamSupport; @Service public class ReviewService { private final ReviewRepository repository; + private final UserService userService; - public ReviewService(ReviewRepository repository) { + public ReviewService(ReviewRepository repository, UserService userService) { this.repository = repository; + this.userService = userService; } - public List getAll() { - return repository.getAll(); + @Transactional(readOnly = true) + public List getAll(long userId) { + if (userId <= 0L) + return StreamSupport.stream(repository.findAll().spliterator(), false).toList(); + userService.get(userId); + return repository.findByUserId(userId); } + @Transactional(readOnly = true) + public Page getAll(long userId, Integer offset, Integer limit) { + if (userId <= 0L) + return repository.findAll(PageRequest.of(offset, limit)); + userService.get(userId); + return repository.findByUserId(userId, PageRequest.of(offset, limit)); + } + + @Transactional(readOnly = true) public ReviewEntity get(Long id) { - return Optional.ofNullable(repository.get(id)).orElseThrow(() -> new NotFoundException(id)); + return repository.findById(id).orElseThrow(() -> new NotFoundException(ReviewEntity.class, id)); } + @Transactional public ReviewEntity create(ReviewEntity entity) { - return repository.create(entity); + if (entity == null) { + throw new IllegalArgumentException("Entity is null"); + } + final UserEntity existUser = userService.get(entity.getUser().getId()); + entity.setUser(existUser); + return repository.save(entity); } - public ReviewEntity update(Long id, ReviewEntity entity) { + @Transactional + public ReviewEntity update(long id, ReviewEntity entity) { final ReviewEntity existsEntity = get(id); - existsEntity.setName(entity.getName()); + userService.get(entity.getUser().getId()); + existsEntity.setUser(entity.getUser()); existsEntity.setText(entity.getText()); - return repository.update(existsEntity); + return repository.save(existsEntity); } - public ReviewEntity delete(Long id) { + @Transactional + public ReviewEntity delete(long id) { final ReviewEntity existsEntity = get(id); - return repository.delete(existsEntity); + repository.delete(existsEntity); + return existsEntity; + } + + @Transactional(readOnly = true) + public Page getCount(int offset, int limit) { + return repository.getReviewCountByUsers(PageRequest.of(offset, limit)); } } diff --git a/src/main/java/ip_2/lab1/types/api/TypeController.java b/src/main/java/ip_2/lab1/types/api/TypeController.java index 3e0b8e3..5b72769 100644 --- a/src/main/java/ip_2/lab1/types/api/TypeController.java +++ b/src/main/java/ip_2/lab1/types/api/TypeController.java @@ -3,7 +3,6 @@ package ip_2.lab1.types.api; import ip_2.lab1.core.configuration.Constants; import ip_2.lab1.types.model.TypeEntity; import ip_2.lab1.types.service.TypeService; -import jakarta.validation.Valid; import org.modelmapper.ModelMapper; import org.springframework.web.bind.annotation.*; diff --git a/src/main/java/ip_2/lab1/types/api/TypeDto.java b/src/main/java/ip_2/lab1/types/api/TypeDto.java index 5ec3e1a..d233953 100644 --- a/src/main/java/ip_2/lab1/types/api/TypeDto.java +++ b/src/main/java/ip_2/lab1/types/api/TypeDto.java @@ -2,19 +2,19 @@ package ip_2.lab1.types.api; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.models.security.SecurityScheme; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.*; public class TypeDto { + @JsonProperty(access = JsonProperty.Access.READ_ONLY) private Long id; @NotBlank + @Size(min = 3, max = 30) private String name; @NotNull @Min(1) + @Size(min = 1, max = 10) private Integer basePrice; - @JsonProperty(access = JsonProperty.Access.READ_ONLY) public Long getId() { return id; } diff --git a/src/main/java/ip_2/lab1/types/model/TypeEntity.java b/src/main/java/ip_2/lab1/types/model/TypeEntity.java index c5f4a2d..145cb91 100644 --- a/src/main/java/ip_2/lab1/types/model/TypeEntity.java +++ b/src/main/java/ip_2/lab1/types/model/TypeEntity.java @@ -1,19 +1,25 @@ package ip_2.lab1.types.model; import ip_2.lab1.core.model.BaseEntity; +import ip_2.lab1.items.model.ItemEntity; +import jakarta.persistence.*; import java.lang.reflect.Type; +import java.util.HashSet; import java.util.Objects; +import java.util.Set; +@Entity +@Table(name = "types") public class TypeEntity extends BaseEntity { + @Column(nullable = false, unique = true, length = 30) private String name; + @Column(nullable = false, length = 10) private Integer basePrice; public TypeEntity() { - super(); } - public TypeEntity(Long id, String name, Integer basePrice) { - super(id); + public TypeEntity(String name, Integer basePrice) { this.name = name; this.basePrice = basePrice; } diff --git a/src/main/java/ip_2/lab1/types/repository/TypeRepository.java b/src/main/java/ip_2/lab1/types/repository/TypeRepository.java index bcd5257..7795a9f 100644 --- a/src/main/java/ip_2/lab1/types/repository/TypeRepository.java +++ b/src/main/java/ip_2/lab1/types/repository/TypeRepository.java @@ -1,11 +1,11 @@ package ip_2.lab1.types.repository; -import ip_2.lab1.core.repository.MapRepository; import ip_2.lab1.types.model.TypeEntity; -import org.springframework.stereotype.Repository; +import org.springframework.data.repository.CrudRepository; import java.util.Map; +import java.util.Optional; -@Repository -public class TypeRepository extends MapRepository { +public interface TypeRepository extends CrudRepository { + Optional findByNameIgnoreCase(String name); } diff --git a/src/main/java/ip_2/lab1/types/service/TypeService.java b/src/main/java/ip_2/lab1/types/service/TypeService.java index 8e5bc7f..4ecf4b1 100644 --- a/src/main/java/ip_2/lab1/types/service/TypeService.java +++ b/src/main/java/ip_2/lab1/types/service/TypeService.java @@ -1,47 +1,64 @@ package ip_2.lab1.types.service; import ip_2.lab1.core.error.NotFoundException; +import ip_2.lab1.items.repository.ItemRepository; import ip_2.lab1.types.model.TypeEntity; import ip_2.lab1.types.repository.TypeRepository; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.lang.reflect.Type; import java.util.List; import java.util.Optional; +import java.util.stream.StreamSupport; @Service public class TypeService { private final TypeRepository repository; + private final ItemRepository itemRepository; - public TypeService(TypeRepository repository) { + public TypeService(TypeRepository repository, ItemRepository itemRepository) { this.repository = repository; + this.itemRepository = itemRepository; } + private void checkName(String name) { + if (repository.findByNameIgnoreCase(name).isPresent()) { + throw new IllegalArgumentException( + String.format("Type with name %s is already exists", name)); + } + } + + @Transactional(readOnly = true) public List getAll() { - return repository.getAll(); + return StreamSupport.stream(repository.findAll().spliterator(), false).toList(); } + @Transactional(readOnly = true) public TypeEntity get(Long id) { - return Optional.ofNullable(repository.get(id)).orElseThrow(() -> new NotFoundException(id)); - } + return repository.findById(id) + .orElseThrow(() -> new NotFoundException(TypeEntity.class, id)); } + @Transactional public TypeEntity create(TypeEntity entity) { - return repository.create(entity); - } + if (entity == null) { + throw new IllegalArgumentException("Entity is null"); + } + checkName(entity.getName()); + return repository.save(entity); } + @Transactional public TypeEntity update(Long id, TypeEntity entity) { final TypeEntity existsEntity = get(id); existsEntity.setName(entity.getName()); existsEntity.setBasePrice(entity.getBasePrice()); - return repository.update(existsEntity); + return repository.save(existsEntity); } public TypeEntity delete(Long id) { final TypeEntity existsEntity = get(id); - return repository.delete(existsEntity); + itemRepository.deleteAllByTypeId(id); + repository.delete(existsEntity); + return existsEntity; } - -// public void deleteAll() { -// repository.deleteAll(); -// } } diff --git a/src/main/java/ip_2/lab1/users/api/UserController.java b/src/main/java/ip_2/lab1/users/api/UserController.java new file mode 100644 index 0000000..58c36d3 --- /dev/null +++ b/src/main/java/ip_2/lab1/users/api/UserController.java @@ -0,0 +1,48 @@ +package ip_2.lab1.users.api; + +import ip_2.lab1.core.configuration.Constants; +import ip_2.lab1.users.model.UserEntity; +import ip_2.lab1.users.service.UserService; +import org.modelmapper.ModelMapper; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping(Constants.API_URL + "/user") +public class UserController { + private final UserService userService; + private final ModelMapper modelMapper; + + public UserController(UserService userService, ModelMapper modelMapper){ + this.userService = userService; + this.modelMapper = modelMapper; + } + + private UserDto toDto(UserEntity entity){ return modelMapper.map(entity, UserDto.class);} + private UserEntity toEntity(UserDto dto){ return modelMapper.map(dto, UserEntity.class);} + + @GetMapping + public List getAll(){ return userService.getAll().stream().map(this::toDto).toList();} + + @GetMapping("/{id}") + public UserDto get(@PathVariable(name = "id") Long id){ return toDto(userService.get(id));} + + @PostMapping() + public UserDto create(@RequestBody UserDto dto){ return toDto(userService.create(toEntity(dto)));} + + @PutMapping("/{id}") + public UserDto update(@PathVariable(name = "id") Long id, @RequestBody UserDto dto){ + return toDto(userService.update(id, toEntity(dto))); + } + + @PutMapping("/updatePassword/{id}") + public UserDto updatePassword(@PathVariable(name = "id") Long id, @RequestParam String password){ + return toDto(userService.updatePassword(id, password)); + } + + @DeleteMapping("/{id}") + public UserDto delete(@PathVariable(name = "id") Long id){ + return toDto(userService.delete(id)); + } +} diff --git a/src/main/java/ip_2/lab1/users/api/UserDto.java b/src/main/java/ip_2/lab1/users/api/UserDto.java new file mode 100644 index 0000000..2a6fe03 --- /dev/null +++ b/src/main/java/ip_2/lab1/users/api/UserDto.java @@ -0,0 +1,41 @@ +package ip_2.lab1.users.api; + +import com.fasterxml.jackson.annotation.JsonProperty; +import ip_2.lab1.reviews.model.ReviewEntity; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; + +import java.util.List; +import java.util.Set; + +public class UserDto { + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Long id; + @NotBlank + @Size(min = 3, max = 30) + private String login; + @NotBlank + @Size(min = 4, max = 30) + private String password; + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + + public String getLogin() { + return login; + } + public void setLogin(String login) { + this.login = login; + } + + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } +} diff --git a/src/main/java/ip_2/lab1/users/model/UserEntity.java b/src/main/java/ip_2/lab1/users/model/UserEntity.java new file mode 100644 index 0000000..fb2f4fc --- /dev/null +++ b/src/main/java/ip_2/lab1/users/model/UserEntity.java @@ -0,0 +1,68 @@ +package ip_2.lab1.users.model; + +import ip_2.lab1.core.model.BaseEntity; +import ip_2.lab1.reviews.model.ReviewEntity; +import ip_2.lab1.types.model.TypeEntity; +import jakarta.persistence.*; +import org.h2.engine.User; + +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +@Entity +@Table(name = "users") +public class UserEntity extends BaseEntity { + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) + @OrderBy("id ASC") + private final Set reviews = new HashSet<>(); + @Column(nullable = false, unique = true, length = 30) + private String login; + @Column(nullable = false, length = 30) + private String password; + + public UserEntity() { + } + + public UserEntity (String login, String password){ + this.login = login; + this.password = password; + } + + public String getLogin(){ return login;} + public void setLogin(String login) { + this.login = login; + } + public String getPassword() { return password; } + public void setPassword(String password) { + this.password = password; + } + + public Set getReviews() { + return reviews; + } + + public void addReview(ReviewEntity review) { + if (review.getUser() != this) { + review.setUser(this); + } + reviews.add(review); + } + + + @Override + public int hashCode() { + return Objects.hash(id, login, password); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + final UserEntity other = (UserEntity) obj; + return Objects.equals(other.getId(), id) && Objects.equals(other.getLogin(), login) + && Objects.equals(other.getPassword(), password); + } +} diff --git a/src/main/java/ip_2/lab1/users/repository/UserRepository.java b/src/main/java/ip_2/lab1/users/repository/UserRepository.java new file mode 100644 index 0000000..32e7b3a --- /dev/null +++ b/src/main/java/ip_2/lab1/users/repository/UserRepository.java @@ -0,0 +1,14 @@ +package ip_2.lab1.users.repository; + +import ip_2.lab1.users.model.UserEntity; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; + +import java.util.Optional; + +public interface UserRepository extends CrudRepository { + Optional findByLoginIgnoreCase(String login); + + @Query("select u from UserEntity u join fetch u.reviews where u.id = ?1") + Optional findByIdForReviewCreate(Long id); +} diff --git a/src/main/java/ip_2/lab1/users/service/UserService.java b/src/main/java/ip_2/lab1/users/service/UserService.java new file mode 100644 index 0000000..8bd61eb --- /dev/null +++ b/src/main/java/ip_2/lab1/users/service/UserService.java @@ -0,0 +1,89 @@ +package ip_2.lab1.users.service; + +import ip_2.lab1.core.error.NotFoundException; +import ip_2.lab1.reviews.model.ReviewEntity; +import ip_2.lab1.reviews.repository.ReviewRepository; +import ip_2.lab1.users.model.UserEntity; +import ip_2.lab1.users.repository.UserRepository; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.StreamSupport; + +@Service +public class UserService { + private final UserRepository repository; + private final ReviewRepository reviewRepository; + + public UserService(UserRepository repository, ReviewRepository reviewRepository){ + this.repository = repository; + this.reviewRepository = reviewRepository; + } + + private void checkLogin(String login) { + if (repository.findByLoginIgnoreCase(login).isPresent()) { + throw new IllegalArgumentException( + String.format("User with login %s is already exists", login)); + } + } + + @Transactional(readOnly = true) + public List getAll(){ + return StreamSupport.stream(repository.findAll().spliterator(), false).toList(); + } + + @Transactional(readOnly = true) + public UserEntity get(Long id){ + return repository.findById(id) + .orElseThrow(() -> new NotFoundException(UserEntity.class, id)); + } + + @Transactional(readOnly = true) + public UserEntity getForReviewCreate(Long id){ + return repository.findByIdForReviewCreate(id) + .orElseThrow(() -> new NotFoundException(UserEntity.class, id)); + } + + @Transactional + public UserEntity create(UserEntity entity){ + if (entity == null){ + throw new IllegalArgumentException("Entity is null"); + } + checkLogin(entity.getLogin()); + return repository.save(entity); + } + + @Transactional + public UserEntity update(Long id, UserEntity entity){ + if (entity == null) + throw new IllegalArgumentException("Entity is null"); + final UserEntity existsEntity = get(id); + existsEntity.setLogin(entity.getLogin()); + return repository.save(existsEntity); + } + + @Transactional + public UserEntity updatePassword(Long id, String password){ + if (password == null) + throw new IllegalArgumentException("Password is null"); + final UserEntity existsEntity = get(id); + if (password.equals(existsEntity.getPassword())) + throw new IllegalArgumentException("It is existing password"); + if (password.contains("1234")) + throw new IllegalArgumentException("Password could not contains numeric sequences"); + if(password.length() > 30 || password.length() < 4) + throw new IllegalArgumentException("Password`s length must be in range 4 and 30 characters"); + existsEntity.setPassword(password); + return repository.save(existsEntity); + } + + @Transactional + public UserEntity delete(Long id){ + final UserEntity existsEntity = get(id); + reviewRepository.deleteAllByUserId(id); + repository.deleteById(id); + return existsEntity; + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8b13789..baf44b8 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,20 @@ +# Server +spring.main.banner-mode=off +server.port=8080 +# Logger settings +# Available levels are: TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF +logging.level.com.example.demo=DEBUG + +# JPA Settings +spring.datasource.url=jdbc:h2:file:./data +spring.datasource.username=sa +spring.datasource.password=password +spring.datasource.driver-class-name=org.h2.Driver +spring.jpa.hibernate.ddl-auto=create +spring.jpa.open-in-view=false +# spring.jpa.show-sql=true +# spring.jpa.properties.hibernate.format_sql=true + +# H2 console +spring.h2.console.enabled=true diff --git a/src/test/java/ip_2/lab1/ItemServiceTest.java b/src/test/java/ip_2/lab1/ItemServiceTest.java new file mode 100644 index 0000000..5ab1e69 --- /dev/null +++ b/src/test/java/ip_2/lab1/ItemServiceTest.java @@ -0,0 +1,88 @@ +package ip_2.lab1; + +import ip_2.lab1.core.error.NotFoundException; +import ip_2.lab1.items.model.ItemEntity; +import ip_2.lab1.items.service.ItemService; +import ip_2.lab1.types.model.TypeEntity; +import ip_2.lab1.types.service.TypeService; +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; + +@SpringBootTest +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class ItemServiceTest { + @Autowired + private ItemService itemService; + + @Autowired + private TypeService typeService; + + private TypeEntity type; + private ItemEntity item; + private ItemEntity item2; + private ItemEntity item3; + + @BeforeEach + void createData(){ + removeData(); + + type = typeService.create(new TypeEntity("Asfalt", 1000)); + item = itemService.create(new ItemEntity(type, 900, 10)); + item2 = itemService.create(new ItemEntity(type, 800, 5)); + item3 = itemService.create(new ItemEntity(type, 700, 100)); + } + + @AfterEach + void removeData(){ + itemService.getAll(0L).forEach(item -> itemService.delete(item.getId())); + typeService.getAll().forEach(type -> typeService.delete(type.getId())); + } + + + @Test + void getTest() { + Assertions.assertThrows(NotFoundException.class, () -> itemService.get(0L)); + } + + @Test + void createTest() { + Assertions.assertEquals(3, itemService.getAll(0L).size()); + Assertions.assertEquals(item, itemService.get(item.getId())); + } + + @Test + void createNullableTest() { + final ItemEntity NullableItem = new ItemEntity(null, null, null); + Assertions.assertThrows(DataIntegrityViolationException.class, () -> itemService.create(NullableItem)); + } + + @Test + void updateTest() { + final int testPrice = 1800; + final int testCount = 20; + final TypeEntity type1 = typeService.create(new TypeEntity("Grunt", 2000)); + final TypeEntity oldType = item.getType(); + final int oldPrice = item.getPrice(); + final int oldCount = item.getCount(); + final ItemEntity newEntity = itemService.update(item.getId(), new ItemEntity(type1, testPrice, testCount)); + Assertions.assertEquals(3, itemService.getAll(0L).size()); + Assertions.assertEquals(newEntity, itemService.get(item.getId())); + Assertions.assertEquals(type1, newEntity.getType()); + Assertions.assertEquals(testPrice, newEntity.getPrice()); + Assertions.assertEquals(testCount, newEntity.getCount()); + Assertions.assertNotEquals(oldType, newEntity.getType()); + Assertions.assertNotEquals(oldPrice, newEntity.getPrice()); + Assertions.assertNotEquals(oldCount, newEntity.getCount()); + } + + @Test + void deleteTest() { + itemService.delete(item3.getId()); + Assertions.assertEquals(2, itemService.getAll(0L).size()); + final ItemEntity last = itemService.get(item2.getId()); + Assertions.assertEquals(item2.getId(), last.getId()); + } +} + diff --git a/src/test/java/ip_2/lab1/ReviewServiceTest.java b/src/test/java/ip_2/lab1/ReviewServiceTest.java new file mode 100644 index 0000000..6f42d41 --- /dev/null +++ b/src/test/java/ip_2/lab1/ReviewServiceTest.java @@ -0,0 +1,74 @@ +package ip_2.lab1; + +import ip_2.lab1.core.error.NotFoundException; +import ip_2.lab1.reviews.model.ReviewEntity; +import ip_2.lab1.reviews.service.ReviewService; +import ip_2.lab1.users.model.UserEntity; +import ip_2.lab1.users.service.UserService; +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class ReviewServiceTest { + @Autowired + private ReviewService reviewService; + @Autowired + private UserService userService; + + private UserEntity user; + private ReviewEntity review; + private ReviewEntity review2; + private ReviewEntity review3; + + @BeforeEach + void createData(){ + removeData(); + + user = userService.create(new UserEntity("Artyom", "1234")); + review = reviewService.create(new ReviewEntity(user, "Good")); + review2 = reviewService.create(new ReviewEntity(user, "Super good")); + review3 = reviewService.create(new ReviewEntity(user, "Not bad")); + } + + @AfterEach + void removeData(){ + reviewService.getAll(0L).forEach(review -> reviewService.delete(review.getId())); + userService.getAll().forEach(user -> userService.delete(user.getId())); + } + + @Test + void getTest() { + Assertions.assertThrows(NotFoundException.class, () -> reviewService.get(0L)); + } + + @Test + void createTest() { + Assertions.assertEquals(3, reviewService.getAll(0L).size()); + Assertions.assertEquals(review, reviewService.get(review.getId())); + } + + @Test + void updateTest() { + final String text = "test"; + final UserEntity user1 = userService.create(new UserEntity("Niyaz", "1234")); + final UserEntity oldUser = review.getUser(); + final String oldText = review.getText(); + final ReviewEntity newEntity = reviewService.update(review.getId(), new ReviewEntity(user1, text)); + Assertions.assertEquals(3, reviewService.getAll(0L).size()); + Assertions.assertEquals(newEntity, reviewService.get(review.getId())); + Assertions.assertEquals(user1, newEntity.getUser()); + Assertions.assertEquals(text, newEntity.getText()); + Assertions.assertNotEquals(oldUser, newEntity.getUser()); + Assertions.assertNotEquals(oldText, newEntity.getText()); + } + + @Test + void deleteTest() { + reviewService.delete(review3.getId()); + Assertions.assertEquals(2, reviewService.getAll(0L).size()); + final ReviewEntity last = reviewService.get(review2.getId()); + Assertions.assertEquals(review2.getId(), last.getId()); + } +} diff --git a/src/test/java/ip_2/lab1/TypeServiceTests.java b/src/test/java/ip_2/lab1/TypeServiceTests.java index f9bb9c8..02f76ee 100644 --- a/src/test/java/ip_2/lab1/TypeServiceTests.java +++ b/src/test/java/ip_2/lab1/TypeServiceTests.java @@ -3,13 +3,11 @@ package ip_2.lab1; import ip_2.lab1.types.service.TypeService; import ip_2.lab1.core.error.NotFoundException; import ip_2.lab1.types.model.TypeEntity; -import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.*; import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; @SpringBootTest @TestMethodOrder(OrderAnnotation.class) @@ -17,47 +15,67 @@ class TypeServiceTests { @Autowired private TypeService typeService; + private TypeEntity type; + + @BeforeEach + void createData() { + removeData(); + + type = typeService.create(new TypeEntity("Asfalt", 2000)); + typeService.create(new TypeEntity("Grunt", 3000)); + typeService.create(new TypeEntity("Asfalt + Grunt", 3500)); + } + + @AfterEach + void removeData() { + typeService.getAll().forEach(item -> typeService.delete(item.getId())); + } + @Test void getTest() { Assertions.assertThrows(NotFoundException.class, () -> typeService.get(0L)); } @Test - @Order(1) void createTest() { - typeService.create(new TypeEntity(null, "Asphalt", 2000)); - typeService.create(new TypeEntity(null, "Grunt", 3000)); - final TypeEntity last = typeService.create(new TypeEntity(null, "Asphalt + grunt", 3500)); Assertions.assertEquals(3, typeService.getAll().size()); - Assertions.assertEquals(last, typeService.get(3L)); + Assertions.assertEquals(type, typeService.get(type.getId())); + } + + @Test + void createNotUniqueTest() { + final TypeEntity nonUniqueType = new TypeEntity("Asfalt", 2000); + Assertions.assertThrows(IllegalArgumentException.class, () -> typeService.create(nonUniqueType)); + } + + @Test + void createNullableTest() { + final TypeEntity nullableType = new TypeEntity(null, null); + Assertions.assertThrows(DataIntegrityViolationException.class, () -> typeService.create(nullableType)); } @Test - @Order(2) void updateTest() { - final String test1 = "TEST"; - final Integer test2 = 1000; - final TypeEntity entity = typeService.get(3L); - final String oldName = entity.getName(); - final Integer oldPrice = entity.getBasePrice(); - final TypeEntity newEntity = typeService.update(3L, new TypeEntity(1L, test1, test2)); + final String test = "TEST"; + final Integer testPrice = 1000; + final String oldName = type.getName(); + final Integer oldPrice = type.getBasePrice(); + final TypeEntity newEntity = typeService.update(type.getId(), new TypeEntity(test, testPrice)); Assertions.assertEquals(3, typeService.getAll().size()); - Assertions.assertEquals(newEntity, typeService.get(3L)); - Assertions.assertEquals(test1, newEntity.getName()); - Assertions.assertEquals(test2, newEntity.getBasePrice()); + Assertions.assertEquals(newEntity, typeService.get(type.getId())); + Assertions.assertEquals(test, newEntity.getName()); + Assertions.assertEquals(testPrice, newEntity.getBasePrice()); Assertions.assertNotEquals(oldName, newEntity.getName()); + Assertions.assertNotEquals(oldPrice, newEntity.getBasePrice()); } @Test - @Order(3) void deleteTest() { - typeService.delete(3L); + typeService.delete(type.getId()); Assertions.assertEquals(2, typeService.getAll().size()); - final TypeEntity last = typeService.get(2L); - Assertions.assertEquals(2L, last.getId()); - final TypeEntity newEntity = typeService.create(new TypeEntity(null, "Asphalt + grunt", 3500)); + final TypeEntity newEntity = typeService.create(new TypeEntity(type.getName(), type.getBasePrice())); Assertions.assertEquals(3, typeService.getAll().size()); - Assertions.assertEquals(4L, newEntity.getId()); + Assertions.assertNotEquals(type.getId(), newEntity.getId()); } } diff --git a/src/test/java/ip_2/lab1/UserServiceTest.java b/src/test/java/ip_2/lab1/UserServiceTest.java new file mode 100644 index 0000000..f19b0fe --- /dev/null +++ b/src/test/java/ip_2/lab1/UserServiceTest.java @@ -0,0 +1,87 @@ +package ip_2.lab1; + +import ip_2.lab1.core.error.NotFoundException; +import ip_2.lab1.users.model.UserEntity; +import ip_2.lab1.users.service.UserService; +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; + +@SpringBootTest +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class UserServiceTest { + @Autowired + private UserService userService; + + private UserEntity entity; + + @BeforeEach + void createData() { + removeData(); + + entity = userService.create(new UserEntity("Artyom", "1234")); + userService.create(new UserEntity("Niyaz", "1234")); + userService.create(new UserEntity("Rostik", "1234")); + } + + @AfterEach + void removeData() { + userService.getAll().forEach(item -> userService.delete(item.getId())); + } + + @Test + void getTest() { + Assertions.assertThrows(NotFoundException.class, () -> userService.get(0L)); + } + + @Test + void createTest() { + Assertions.assertEquals(3, userService.getAll().size()); + Assertions.assertEquals(entity, userService.get(entity.getId())); + } + + @Test + void createNotUniqueTest() { + final UserEntity nonUniqueEntity = new UserEntity("Artyom", "1234"); + Assertions.assertThrows(IllegalArgumentException.class, () -> userService.create(nonUniqueEntity)); + } + + @Test + void createNullableTest() { + final UserEntity nullableEntity = new UserEntity(null, null); + Assertions.assertThrows(DataIntegrityViolationException.class, () -> userService.create(nullableEntity)); + } + + @Test + void updateTest() { + final String login = "TEST"; + final String oldLogin = entity.getLogin(); + final String oldPassword = entity.getPassword(); + final UserEntity newEntity = userService.update(entity.getId(), new UserEntity(login, null)); + Assertions.assertEquals(3, userService.getAll().size()); + Assertions.assertEquals(newEntity, userService.get(entity.getId())); + Assertions.assertEquals(login, newEntity.getLogin()); + Assertions.assertNotEquals(oldLogin, newEntity.getLogin()); + } + + @Test + void updatePasswordTest(){ + final String password = "TEST"; + final String oldPassword = entity.getPassword(); + final UserEntity newEntity = userService.updatePassword(entity.getId(), password); + Assertions.assertEquals(newEntity, userService.get(entity.getId())); + Assertions.assertEquals(password, newEntity.getPassword()); + Assertions.assertNotEquals(oldPassword, newEntity.getPassword()); + } + + @Test + void deleteTest() { + userService.delete(entity.getId()); + Assertions.assertEquals(2, userService.getAll().size()); + + final UserEntity newEntity = userService.create(new UserEntity(entity.getLogin(), entity.getPassword())); + Assertions.assertEquals(3, userService.getAll().size()); + Assertions.assertNotEquals(entity.getId(), newEntity.getId()); + } +}