java - Spring Data findOne() NullPointerException -
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