当前位置: 首页 > 知识库问答 >
问题:

Spring保存带有外键的复合主键

单于承
2023-03-14

我在使用复合主键创建实体时遇到问题,该键也是外键。这是我的表和关系表原理图。当我想创建新闻实体时,我收到了带有null creatingnews的错误消息。新闻翻译有复合主键,外键引用到新闻表。

这是我的代码:

新闻聚合

@AggregateRoot
@Entity
@Table(name = "news")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class NewsAggregate extends AuditingAggregateRoot implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "news_id")
    private Long newsId;

    @ManyToOne
    @JoinColumn(name = "id")
    private UserAggregate authorId;

    @Column(name = "publish_time")
    private ZonedDateTime publishTime;

    @Column(name = "published", nullable = false)
    private boolean published = false;

    @ManyToMany
    @JoinTable(
        name = "tags_news",
        joinColumns = {@JoinColumn(name = "news_id", referencedColumnName = "news_id")},
        inverseJoinColumns = {@JoinColumn(name = "tag", referencedColumnName = "tag")})
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    private Set<Tags> tags = new HashSet<Tags>();

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL,
        orphanRemoval = true)
    private List<NewsTranslation> newsTranslation;



    public NewsAggregate(UserAggregate authorId, Set<Tags> tags, String langCode,
                         String title, String shortDescription, String longDescription) {
        this.authorId = authorId;
        this.tags = tags;
        newsTranslation.add(
            new NewsTranslation(this, langCode, title, shortDescription, longDescription)
        );


    }

//Getters, equal, hashCode

新闻翻译

@Entity
@Table(name = "news_translation")
/*@IdClass(NewsLangId.class)*/
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class NewsTranslation implements Serializable {

    private static final long serialVersionUID = 7576921328990303444L;

    @EmbeddedId
    private NewsLangId newsLangId;

    @Column(name = "title", length = TITLE_MAX_LENGTH, nullable = false)
    private String title;

    @Column(name = "short_description", length = SHORT_DESC_MAX_LENGTH, nullable = false)
    private String shortDescription;

    @Column(name = "long_description", nullable = false)
    private String longDescription;

    @ManyToOne
    @JoinColumn(name = "news_id", insertable = false, updatable = false)
    private NewsAggregate newsAggregate;

    @ManyToOne
    @JoinColumn(name = "lang_code", insertable = false, updatable = false)
    private Languages languages;

    public NewsTranslation() {
    }

    protected NewsTranslation(NewsAggregate newsAggregate, String langCode,String title, String shortDescription, String longDescription) {
        System.out.println(">>>>>>>>>>>>>>>.. NewsTranslation constructor");
        this.title = title;
        this.shortDescription = shortDescription;
        this.longDescription = longDescription;
        this.newsAggregate = newsAggregate;
        this.languages = new Languages();
        this.newsLangId = new NewsLangId(this.newsAggregate.getId(), langCode);
        System.out.println(">>>>>>>>> NewsTranslation : title = "+this.title+", shortDescription = "+this.shortDescription+
        ", longDescription = "+this.longDescription+", newsAggregate = "+this.newsAggregate +", languages = "+this.languages);

    }

// getters, setters

标签

@Entity
@Table(name = "tags")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Tags implements Serializable {
private static final long serialVersionUID = 2995101252921266446L;

@Id
@Column(name = "tag", length = TAG_MAX_LENGTH, unique = true)
private String tag;

public Tags() {
}

private Tags(Builder builder) {
    this.tag = Preconditions.checkNotNull(builder.tag);
}

public void setTag(String tag) {
    this.tag = tag;
}

新闻语言ID

@Embeddable
public class NewsLangId implements Serializable {

private static final long serialVersionUID = -4822628791720244835L;

@Column(name = "news_id")
private long newsId;
@Column(name = "lang_code")
private String langCode;

public NewsLangId() {
}

public NewsLangId(long newsId, String langCode) {
    System.out.println("Create NewsLangId: "+newsId+", "+langCode);
    this.newsId = newsId;
    this.langCode = langCode;
}

// getters, setters, equal, hashcode

在NewsFactory中,我希望使用NewsTranslation创建NewsAggregate,但有错误消息NullPointer。

新闻工厂

Set<Tags> tagsSet = new HashSet<Tags>(tagsRepository.findAll());
        UserAggregate login = userRepository.findOneByLogin("admin").get();


        NewsAggregate news = new NewsAggregate(login,tagsSet, createNewsDto.getLangCode(), createNewsDto.getTitle(),
            createNewsDto.getShortDescription(),createNewsDto.getLongDescription());

        log.info(">>>>>>>>>>>> NewsFactory: newsAggregate = "+news);

        return news;

错误:

java.lang.NullPointerException: null
    at it.seiton.aexea.domain.model.news.NewsTranslation.<init>(NewsTranslation.java:55)
    at it.seiton.aexea.domain.model.news.NewsAggregate.<init>(NewsAggregate.java:61)
    at it.seiton.aexea.domain.model.news.NewsFactory.createNews(NewsFactory.java:55)
    at it.seiton.aexea.domain.service.impl.NewsServiceDefault.createNews(NewsServiceDefault.java:29)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
    at com.sun.proxy.$Proxy184.createNews(Unknown Source)
    at it.seiton.aexea.web.rest.NewsResource.createNews(NewsResource.java:43)
    at it.seiton.aexea.web.rest.NewsResource$$FastClassBySpringC530334.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
    at it.seiton.aexea.aop.logging.LoggingAspect.logAround(LoggingAspect.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:620)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:609)
    at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:59)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
    at it.seiton.aexea.web.rest.NewsResource$$EnhancerBySpringCGLIB$$c9591bb7.createNews(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:870)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
    at com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(AbstractInstrumentedFilter.java:104)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at com.hazelcast.web.WebFilter.doFilter(WebFilter.java:360)
    at io.undertow..core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextHeaderFilter.doFilterInternal(EndpointWebMvcAutoConfiguration.java:237)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:112)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:207)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doOncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.security.handlers.AbstractConfiityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
    at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.SessionRestoringHandler.handleRequest(SessionRestoringHandler.java:119)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:284)
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:174)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:793)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

对我的英语很抱歉。

共有1个答案

王曜文
2023-03-14

我通过更改生成的主键解决了我的问题。现在java生成id,而不是postgresql。

新闻聚合

@AggregateRoot
@Entity
@Table(name = "news")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class NewsAggregate extends AuditingAggregateRoot implements Serializable {
    private static final Logger log = LoggerFactory.getLogger(NewsAggregate.class);


@Id
@Column(name = "news_id")
private String newsId;

@ManyToOne
@JoinColumn(name = "author_id", referencedColumnName = "id")
private UserAggregate authorId;

@Column(name = "publish_date")
private ZonedDateTime publishTime = null;

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(
    name = "tags_news",
    joinColumns = {@JoinColumn(name = "news_id", referencedColumnName = "news_id")},
    inverseJoinColumns = {@JoinColumn(name = "tag", referencedColumnName = "tag")})
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Tags> tags = new HashSet<Tags>();

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "news_id", referencedColumnName = "news_id")
@Fetch(FetchMode.JOIN)
private List<NewsTranslation> newsTranslation = new ArrayList<NewsTranslation>();

public NewsAggregate(Set<Tags> tags, UserAggregate authorId) {
    this.newsId = generateId(authorId.getId());
    this.tags = tags;
    this.authorId = authorId;
    this.publishTime = ZonedDateTime.now();
}

private NewsAggregate(Builder builder) {
    this.authorId = Preconditions.checkNotNull(builder.authorId);
    this.publishTime = builder.publishTime;
    this.tags = Preconditions.checkNotNull(builder.tags);
    this.newsTranslation = Preconditions.checkNotNull(builder.newsTranslation);
}

private String generateId(long userId) {
    return ZonedDateTime.now().toInstant().toEpochMilli() + "_" + userId;
}

public static NewsAggregate createNews(Set<Tags> tags, UserAggregate authorId, CreateNewsDto createNewsDto) {

    NewsAggregate news = new NewsAggregate(tags, authorId);
    log.info(">>>>>>>>>>>>>>>>>> news_id = "+news.getNewsId());
    NewsLangId newsLangId = new NewsLangId(news.getNewsId(), "en");

    NewsTranslation newsTranslation = new NewsTranslation(newsLangId, createNewsDto.getTitle(),
        createNewsDto.getShortDescription(), createNewsDto.getLongDescription());

    List<NewsTranslation> newsTranslations = new ArrayList<>();
    newsTranslations.add(newsTranslation);

    news.addTranslation(newsTranslations);
    return news;
}

private void addTranslation(List<NewsTranslation> newsTranslations) {
    this.newsTranslation = newsTranslations;
}

谢谢大家的关注。我希望这将是有益的。

 类似资料:
  • 问题内容: 我使用spring数据休息作为基础。但是当实体具有复合主键时,我不知道如何通过提供主键来获得实体。 河类: RiverPK课程: RiverDAO类: 然后,我可以通过调用get http:// localhost:8080 / river / 获取河流数据,还可以通过调用post http:// localhost:8080 / river / {river json} 为db创建新

  • 问题内容: 我必须与Hibernate合作,但我不确定如何解决此问题,我有2个具有1..n关系的表,如下所示: 如何使用Hibernate进行管理? 我不知道如何声明将包含主键一部分的外键。 我的数据库架构是从Hibernate模型生成的。 问题答案: 我找到了解决此问题的两种方法。 第一个是一种解决方法,没有第二个那么整洁。 将实体的主键定义为包含,和的复合键,首先将假定为主键的内容定义为唯一约

  • 我有一个实体,它的复合主键由两个字段组成,其中一个也是复合外键的一部分。 背景:我有实体<代码>人员 、<代码>区域 和<代码>会话 。 与具有多对多关系,使用称为“和实体。 所以,我有,主键为(,)。本身是的外键。 也有一个字段。我希望(,)是的复合外键。 我的PersonSession代码: } 这看起来不错,它在数据库中创建了所有正确的关系。当我尝试插入个性化会话对象时,问题就出现了——ar

  • 我在jpa/Hibernate中映射复合键时遇到了问题。父实体和子实体都具有复合主键。 在运行时保存它时会出现以下异常: 我认为这是虚假的,因为有getter和setter。如果在priceRequestLegModel上使用mappedby=“leg”,在allocationModel上使用@mapsid,也会出现同样的错误。有人能指出我在这里做错了什么吗?

  • 问题内容: 我有一个类似的问题,如下所示,但解决方案无法解决我的问题。 休眠复合主键包含复合外键,如何映射 我正在尝试加入2个表,每个表都有一个带有部分外键引用的复合主键。 在一个: 在BPK中: 上面的方法给我这个异常: 你能帮忙吗? 问题答案: 假设f1和F2唯一标识A并存在于APK中,则可以通过几种方式使用JPA 2.0的派生ID。最容易显示的是: 这里的关键点是B对A的引用控制了外键字段f

  • 问题内容: 我有一个类似的问题,如下所示,但解决方案无法解决我的问题。 休眠复合主键包含复合外键,如何映射 我正在尝试加入2个表,每个表都有一个带有部分外键引用的复合主键。 在一个: 在BPK中: 上面的方法给我这个异常: 你能帮忙吗? 问题答案: 假设f1和F2唯一标识A并存在于APK中,则可以通过几种方式使用JPA 2.0的派生ID。最容易显示的是: 这里的关键点是B对A的引用控制了外键字段f