Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring数据JPA不适用于CascaseType.PERSIST和@OneToOne_Java_Hibernate_Jpa_Spring Data_Spring Data Jpa - Fatal编程技术网

Java Spring数据JPA不适用于CascaseType.PERSIST和@OneToOne

Java Spring数据JPA不适用于CascaseType.PERSIST和@OneToOne,java,hibernate,jpa,spring-data,spring-data-jpa,Java,Hibernate,Jpa,Spring Data,Spring Data Jpa,我在一个小项目中使用SpringDataJPA来列出一些信息。我有一个类LogEntry,它表示GUI上网格中的一行。其他类用于添加/显示更详细的信息,如上传/下载文件的功能。我将文件数据和元信息分为两个类/表。我的类之间的关系如下:LogEntry->Comment->FileReference->FileData FileReference.java @Entity public class FileReference extends AbstractEntity { privat

我在一个小项目中使用SpringDataJPA来列出一些信息。我有一个类LogEntry,它表示GUI上网格中的一行。其他类用于添加/显示更详细的信息,如上传/下载文件的功能。我将文件数据和元信息分为两个类/表。我的类之间的关系如下:
LogEntry
->
Comment
->
FileReference
->
FileData

FileReference.java

@Entity
public class FileReference extends AbstractEntity {

    private static final long serialVersionUID = 3942449578983368585L;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = false)
    private FileData fileData;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private int size;
}
@Entity
public class FileData extends AbstractEntity {

    private static final long serialVersionUID = 6706563782575452010L;

     @Lob
     byte[] byteArray;
}
public interface LogEntryRepo<LogEntry> extends JpaRepository<LogEntry, ObjectKey> {
}
FileData.java

@Entity
public class FileReference extends AbstractEntity {

    private static final long serialVersionUID = 3942449578983368585L;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = false)
    private FileData fileData;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private int size;
}
@Entity
public class FileData extends AbstractEntity {

    private static final long serialVersionUID = 6706563782575452010L;

     @Lob
     byte[] byteArray;
}
public interface LogEntryRepo<LogEntry> extends JpaRepository<LogEntry, ObjectKey> {
}
LogEntryRepo.java

@Entity
public class FileReference extends AbstractEntity {

    private static final long serialVersionUID = 3942449578983368585L;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = false)
    private FileData fileData;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private int size;
}
@Entity
public class FileData extends AbstractEntity {

    private static final long serialVersionUID = 6706563782575452010L;

     @Lob
     byte[] byteArray;
}
public interface LogEntryRepo<LogEntry> extends JpaRepository<LogEntry, ObjectKey> {
}
公共接口LogEntryRepo扩展了JpaRepository{
}
访问我的实体

@Component
@Transactional(readOnly = true)
public class LogEntryServiceImpl implements LogEntryService {

    @Autowired
    LogEntryRepo repo;

    @Autowired
    FileReferenceRepo fileReferenceRepo;

    /**
     * save a changed LogEntry
     */
    @Override
    @Secured(Roles.ROLE_WRITE)
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public void saveLogEntry(LogEntry logEntry) {
        if (logEntry != null) {
            LogEntry one = repo.getOne(logEntry.getObjectKey());
            if (one != null) {
                if (one.isAudited()) {
                    throw new AlreadyAuditedException();
                }
            }
        }
        repo.save(logEntry);
    }

    @Override
    @Secured(Roles.ROLE_READ_ONLY)
    @Transactional(readOnly = true)
    public List<LogEntry> loadAll() {
        List<LogEntry> findAll = repo.findAll();
        for (LogEntry logEntry : findAll) {
            setNullForFileData(logEntry); // avoid serialization problems with lazy loading proxies
        }
        return findAll;
    }

    @Override
    @Secured(Roles.ROLE_READ_ONLY)
    @Transactional(readOnly = true)
    public FileReference loadFileData(ObjectKey key) {
        FileReference fileReference = fileReferenceRepo.findOne(key);
        // fileData ist lazy loaded. call once to load it from db.
        fileReference.getFileData().getObjectKey();
        return fileReference;
    }
}
@组件
@事务(只读=真)
公共类LogEntryServiceImpl实现LogEntryService{
@自动连线
LogEntryRepo回购;
@自动连线
filereferencepo filereferencepo;
/**
*保存更改的日志条目
*/
@凌驾
@安全(角色。角色\写入)
@事务性(只读=错误,传播=传播。需要\u新建)
公共无效保存日志项(日志项日志项){
if(logEntry!=null){
LogEntry one=repo.getOne(LogEntry.getObjectKey());
如果(一!=null){
如果(一个.isAudited()){
抛出新的AlreadyAuditedException();
}
}
}
回购保存(日志输入);
}
@凌驾
@安全(角色。角色只读)
@事务(只读=真)
公共列表loadAll(){
List findAll=repo.findAll();
用于(日志条目:findAll){
setNullForFileData(logEntry);//避免延迟加载代理的序列化问题
}
返回findAll;
}
@凌驾
@安全(角色。角色只读)
@事务(只读=真)
公共文件引用loadFileData(ObjectKey){
FileReference FileReference=filereferencepo.findOne(键);
//文件数据延迟加载。请调用一次以从数据库加载它。
fileReference.getFileData().getObjectKey();
返回文件引用;
}
}
通过这种分离,我可以读取所有
LogEntry
s,而无需从数据库加载每个文件,但我仍然能够显示文件的元信息并提供下载方法。我在每个关系上都使用CascadeType.ALL。这非常有效,直到我尝试更改
注释中已经存在的一些数据。应用程序试图保存一个
FileReference
,其中对
FileData
的引用为空,这是不允许的。然后我尝试将关系
FileReference
->
FileData
更改为
CascadeType.PERSIST
,但这会导致在尝试保存
注释时出现异常

org.springframework.orm.jpa.JpaObjectRetrievalFailureException:无法找到id为123的..文件数据;嵌套异常为javax.persistence.EntityNotFoundException:无法找到id为PersistentStringObjectKey 123的..文件数据

如果没有
CascadeType.MERGE
,spring数据似乎无法处理这个问题。我想到的唯一两个解决方案是,我使用
CascadeType.ALL
,当我必须更改和更新
Comment
时,我为所有
FileReferences
加载
FileData
,然后保存
Comment
,或者我不使用CascadeType.ALL,并制作一个DAO,在其中保存每个对象的每个引用,在存储“主”对象之前。但这一点都不好

问题:
有人知道如何使用
CasecadeType
s实现我的目标的正确方法吗?不要在每次选择时加载
FileData
,也不要在将更改保存到其他实体之前预加载它?

因为java insert
BLOB
BD
中需要插入和更新,而不是只插入,所以
cascade={CascadeType.PERSIST,CascadeType.MERGE}
是必需的。

首先,Spring是不相关的。您的JPA提供程序是Hibernate,而不是Spring。其次,问题是代码,您没有发布它。要在不加载现有文件数据的情况下获取对该文件数据的引用,只需使用
EntityManager.getReference()
(或
JpaRepository.getOne()
)我使用spring数据jpa,因此我不直接使用jpa。我将编辑问题和代码,了解如何访问我的实体。我希望在不加载Yes的情况下获得
日志条目的列表,而不是单个
文件数据,因此我建议使用JpaRepository.getOne().JpaRepository是Spring-data-jpa中的一个类。也许我不理解你。加载一个文件数据不是问题。我提供了一个Web服务,我有三个用例。一个是加载一个日志项列表。对于这个用例,我不想加载所有与我加载的日志项相关的文件数据。第二个用例是,我想ange LogEntry中的值。在这种情况下,我不想加载FileData。问题是,FileData的引用为null,因为我从外部传递LogEntry(因此没有延迟加载代理)。第三种情况是,我只想加载一个FileData供用户下载。这没有问题。我更新了我的问题如何访问我的实体