i think i'm missing core concept, because encounter several problems, let's start one: when user subscription persisted in database , try using findone(id), nullpointerexception. tried debug deep inside generated code , appears reason hashcode() of subscription object called, unclear reason has id set , other properties null, because (probably) take part in hashcode() method calling own hashcode(), exception.
so want user part of many communities, in each of them can create subscription content. when first call subscriptioncontroller, goes fine , creates user, subscription , community, can see them in database, good. when call userrepository.findone(), crudrepository, inside userserivce - exception.
i've been trying figure out 2 weeks , no luck, hope can spend time helping me this. below classes:
user:
@entity @data @noargsconstructor public class user { @column(nullable = false) @id private integer id; @onetomany(mappedby = "user", fetch = fetchtype.eager, cascade = cascadetype.all) @jsonignore set<subscription> subscriptions; @onetomany(fetch = fetchtype.eager, cascade = cascadetype.all) @jointable( joincolumns = {@joincolumn(name = "user_id", referencedcolumnname = "id")}, inversejoincolumns = {@joincolumn(name = "payment_id", referencedcolumnname = "id", unique = true)} ) @jsonignore set<payment> payments; public user(integer userid) { this.id = userid; } } subscription:
@entity @data @noargsconstructor public class subscription { @column @id @generatedvalue(strategy = generationtype.auto) @jsonignore private integer id; @manytoone(cascade = {cascadetype.merge, cascadetype.refresh}) @joincolumn(name = "user_id", nullable = false) private user user; @manytoone(cascade = {cascadetype.merge, cascadetype.refresh}) @joincolumn(name = "community_id", nullable = false) private community community; @column(nullable = false) private boolean isactive; @column(nullable = false) private date enddate; @onetomany(fetch = fetchtype.eager, cascade = cascadetype.all) @jointable( joincolumns = {@joincolumn(name = "subscription_id", referencedcolumnname = "id")}, inversejoincolumns = {@joincolumn(name = "payment_id", referencedcolumnname = "id", unique = true)} ) private set<payment> payments; public subscription(user user, community community, boolean isactive) { this.user = user; this.community = community; this.isactive = isactive; this.enddate = new date(); } } community:
@data @entity @noargsconstructor public class community { @column(nullable = false) @id private integer id; @onetomany(mappedby = "community", fetch = fetchtype.lazy, cascade = {cascadetype.merge, cascadetype.refresh}) @jsonignore private set<subscription> subscriptions; public community(integer communityid) { this.id = communityid; } } i have services each of them:
userservice:
@service public class userservice implements iservice<user> { @autowired private userrepository userrepository; @transactional public user get(@notnull integer userid) { user user = userrepository.findone(userid); if (user == null) return userrepository.save(new user(userid)); return user; } @override public user save(@valid user user) { return userrepository.save(user); } } subscriptionservice:
@service public class subscriptionservice implements iservice<subscription> { @autowired subscriptionrepository subscriptionrepository; @autowired paymentrepository paymentrepository; @override public subscription get(@notnull integer id) { return subscriptionrepository.findone(id); } public subscription getbyuserandcommunity(@valid user user, @valid community community) { subscription subscription = subscriptionrepository.findbyuserandcommunity(user, community); if (subscription != null) return subscription; subscription = new subscription(user, community, false); return subscriptionrepository.save(subscription); } @transactional public subscription activate(@valid subscription subscription, @valid payment payment, @future date enddate) { paymentrepository.save(payment); set<payment> payments = subscription.getpayments(); if (payments == null) payments = new hashset<>(); payments.add(payment); subscription.setenddate(enddate); subscription.setisactive(true); return subscriptionrepository.save(subscription); } @override public subscription save(@valid subscription e) { return subscriptionrepository.save(e); } } and communityservice:
@service public class communityservice implements iservice<community> { @autowired private communityrepository communityrepository; @override @transactional public community get(@notnull integer id) { community community = communityrepository.findone(id); if (community == null) return communityrepository.save(new community(id)); return community; } @override public community save(@valid community community) { return communityrepository.save(community); } } controller:
@restcontroller public class subscriptioncontroller { @autowired private subscriptionservice subscriptionservice; @autowired private communityservice communityservice; @autowired private paymentservice paymentservice; @postmapping("/subscribe") public responseentity<subscription> subscribe(@requestparam("communityid") integer communityid, @requestbody @valid payment payment) { if(!paymentservice.checkpayment(payment)) return responseentity .status(httpstatus.bad_request) .body(null); vkauthentication vkauthentication = (vkauthentication) securitycontextholder.getcontext().getauthentication(); user user = vkauthentication.getuser(); community community = communityservice.get(communityid); subscription subscription = subscriptionservice.getbyuserandcommunity(user, community); calendar calendar = calendar.getinstance(); date newenddate = dateutils.adddays(new date(), calendar.getactualmaximum(calendar.day_of_month)); subscription = subscriptionservice.activate(subscription, payment, newenddate); return responseentity .status(httpstatus.ok) .body(subscription); } } and here's stack trace:
java.lang.nullpointerexception: null @ org.hibernate.engine.internal.statefulpersistencecontext.getloadedcollectionownerornull(statefulpersistencecontext.java:786) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] @ org.hibernate.event.spi.abstractcollectionevent.getloadedownerornull(abstractcollectionevent.java:58) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] @ org.hibernate.event.spi.initializecollectionevent.<init>(initializecollectionevent.java:22) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] @ org.hibernate.internal.sessionimpl.initializecollection(sessionimpl.java:1989) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] @ org.hibernate.collection.internal.abstractpersistentcollection$4.dowork(abstractpersistentcollection.java:570) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] @ org.hibernate.collection.internal.abstractpersistentcollection.withtemporarysessionifneeded(abstractpersistentcollection.java:252) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] @ org.hibernate.collection.internal.abstractpersistentcollection.initialize(abstractpersistentcollection.java:566) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] @ org.hibernate.collection.internal.abstractpersistentcollection.read(abstractpersistentcollection.java:135) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] @ org.hibernate.collection.internal.persistentset.hashcode(persistentset.java:430) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] @ zhiyest.subscriptionsbackend.domain.user.hashcode(user.java:14) ~[classes/:na] @ zhiyest.subscriptionsbackend.domain.subscription.hashcode(subscription.java:15) ~[classes/:na] @ java.util.hashmap.hash(hashmap.java:338) ~[na:1.8.0_111] @ java.util.hashmap.put(hashmap.java:611) ~[na:1.8.0_111] @ java.util.hashset.add(hashset.java:219) ~[na:1.8.0_111] @ java.util.abstractcollection.addall(abstractcollection.java:344) ~[na:1.8.0_111] @ org.hibernate.collection.internal.persistentset.endread(persistentset.java:327) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] @ org.hibernate.engine.loading.internal.collectionloadcontext.endloadingcollection(collectionloadcontext.java:234) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] @ org.hibernate.engine.loading.internal.collectionloadcontext.endloadingcollections(collectionloadcontext.java:221) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] @ org.hibernate.engine.loading.internal.collectionloadcontext.endloadingcollections(collectionloadcontext.java:194) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] @ org.hibernate.loader.plan.exec.process.internal.collectionreferenceinitializerimpl.endloading(collectionreferenceinitializerimpl.java:154) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] @ org.hibernate.loader.plan.exec.process.internal.abstractrowreader.finishloadingcollections(abstractrowreader.java:249) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] @ ... i don't understand why call subscription.hashcode() when it's findone() user...
upd:
at org.springframework.data.repository.core.support.surroundingtransactiondetectormethodinterceptor.invoke(surroundingtransactiondetectormethodinterceptor.java:57) ~[spring-data-commons-1.13.4.release.jar:na] ... @ zhiyest.subscriptionsbackend.logging.logger.logaround(logger.java:29) ~[classes/:na] ... @ zhiyest.subscriptionsbackend.services.userservice$$enhancerbyspringcglib$$6e00bac4.get(<generated>) ~[classes/:na] @ zhiyest.subscriptionsbackend.security.vkauthenticationprovider.authenticate(vkauthenticationprovider.java:23) ~[classes/:na] @ zhiyest.subscriptionsbackend.security.vkauthenticationprovider$$fastclassbyspringcglib$$24f3d662.invoke(<generated>) ~[classes/:na] ... @ zhiyest.subscriptionsbackend.security.vkauthenticationprovider$$enhancerbyspringcglib$$4d8d8001.authenticate(<generated>) ~[classes/:na] @ org.springframework.security.authentication.providermanager.authenticate(providermanager.java:174) ~[spring-security-core-4.2.3.release.jar:4.2.3.release] @ org.springframework.security.authentication.providermanager.authenticate(providermanager.java:199) ~[spring-security-core-4.2.3.release.jar:4.2.3.release] @ org.springframework.security.access.intercept.abstractsecurityinterceptor.authenticateifrequired(abstractsecurityinterceptor.java:354) ~[spring-security-core-4.2.3.release.jar:4.2.3.release] @ org.springframework.security.access.intercept.abstractsecurityinterceptor.beforeinvocation(abstractsecurityinterceptor.java:229) ~[spring-security-core-4.2.3.release.jar:4.2.3.release] ...
i guess problem @data.
this lombok annotation cause of recursive dependencies (tostring() , hashcode()). try use @getter , @setter instead of @data.
i hope help.
Comments
Post a Comment