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

用@Mapsid实现双向@OneToOne的级联

黄昊
2023-03-14
@Entity
public class Phone {
    
   @Id
   private Long id;
    
   @OneToOne
   @MapsId
   @JoinColumn(name = "id")
   private User user;
    
   public Long getId() {
       return id;
   }
   public void setId(final Long id) {
       this.id = id;
   }
    
   public User getUser() {
      return user;
   }
   public void setUser(final User user) {
      this.user = user;
   }
}
        
@Entity
public class User {

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;
    
   @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
   private Phone phone;
    
   public Long getId() {
       return id;
   }
   public void setId(final Long id) {
       this.id = id;
   }
    
   public Phone getPhone() {
       return phone;
   }
   public void setPhone(final Phone phone) {
       this.phone = phone;
   }
}

控制器:

@RestController
@RequestMapping
public class UserController {
    
   private final UserService userService;
    
   public UserController(final UserService userService) {
       this.userService = userService;
   }
    
   @GetMapping("/demo")
   public void createUserAndAddPhone() {
       final User user = new User();
       userService.save(user);
       final Phone phone = new Phone();
    
       phone.setUser(user);
       user.setPhone(phone);
       userService.update(user);
   }
}

存储库:

public interface UserRepository  extends PagingAndSortingRepository<User, Long> {
}

序列:

@Service
public class UserService {
    
   private final UserRepository userRepository;
    
   public UserService(final UserRepository userRepository) {
       this.userRepository = userRepository;
   }
    
   @Transactional
   public void save(final User user) {
       userRepository.save(user);
   }
    
   @Transactional
   public void update(final User user) {
       userRepository.save(user);
   }
}
CREATE TABLE `phone` (
   `id` bigint(20) NOT NULL,
   PRIMARY KEY (`id`)
);
    
CREATE TABLE `user` (
   `id` bigint(20) NOT NULL AUTO_INCREMENT,
   PRIMARY KEY (`id`)
)
spring:
   datasource:
      url: jdbc:mysql://localhost:3308/demo?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false&allowPublicKeyRetrieval=true
      username: root
      password: 123456
      driver-class-name: com.mysql.jdbc.Driver
   jpa:
      database-platform: org.hibernate.dialect.MySQL5Dialect
      hibernate:
         ddl-auto: validate
<?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    
    <properties>
        <java.version>1.8</java.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.code.findbugs</groupId>
            <artifactId>jsr305</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
insert into `user` 
values ( )

-- Generated identifier: 13, using strategy: org.hibernate.id.ForeignGenerator
                
insert into `phone` (`id`)  values (?)
-- Binding parameter [1] as [BIGINT] - [13]

共有1个答案

谭飞掣
2023-03-14

啊,最后,这是一个冬眠错误(HHH-12436)。

在纯hibernate应用程序中,可以通过以下用例进行复制:

Session session = sessionFactory.openSession();

Transaction tr1 = session.beginTransaction();
User user = new User();
session.persist(user);
tr1.commit();

Transaction tr2 = session.beginTransaction();
Phone newPhone = new Phone();
user.setPhone(newPhone);
newPhone.setUser(user);
session.merge(user);
tr2.commit();

session.close();

从上面的链接可以看到,它在Hibernate5.4分支中得到了修复。

 类似资料:
  • 问题内容: 我有2个类:User和UserPicture具有1:1的关系。 UserPicture中的“ user”将被加载,而UserPicture中的“ userPicture”则不会加载-我错了吗? 编辑 必须添加,我只是创建一个UserPicture并插入它们(使用现有的userId)-也许我需要在UserPicture中级联“ user”? 问题答案: 您必须映射您的课程。

  • 问题内容: 假设我有个人 和工作 提取时,我无法将Person和Job映射到其他实体。 我在做什么错? 问题答案: 您的代码应为: (尝试从工作中删除重复的列’person_id’) 或其他共享主键的方法:

  • 我最近开始研究Hibernate,并在研究映射。在我的场景中,我有一个可以拥有多辆车的用户。在执行双向映射时,在第二个表中生成的列,因为如果使用此双向映射,我将获得空值。我试过调试,但没用。 用户etails.java 交通工具Java语言 冬眠之石。Java语言 输出: 我也发现这有点难以理解为什么我们应该选择双向而不是单向映射。

  • 我试图在JPA2.1中保存一个实体。我有三个表--MVCollection、MVCollectionVersion(它是MVCollection的版本)和MVBelomsCollection(它是属于一个版本的项)。MVCollection的主键是生成的序列号。当我生成一个带有版本(不包含任何项)的集合时,我使用@mapsid,生成的ID在子级中使用。然而,我似乎不能理解我如何能复制这与项目。 M

  • 第404页的“Java持久性2.0,最终发布”有以下示例: 示例3:从一个可嵌入类到另一个实体的一对一关联。 我希望员工内部有多个位置详细信息: 如何更改实体ParkingSpot以指向集合表EMP_LOCATION内的可嵌入Location细节。 应该是 替换为@ElementCollection? 非常感谢。

  • 我定义了具有@OneToOne双向关系的实体。 关系的所有者站点(子类): 其他站点(父类): 当我试图坚持有子集的父母(不坚持),然后我得到了例外 TransientPropertyValueException:对象引用未保存的临时实例-在刷新之前保存临时实例 这看起来可以理解。 但当我定义具有双向一对一/多对一关联的实体时,如: 此关系的所有者站点: 关系的另一面: 并尝试持久化具有子集合集(