`
rustlingwind
  • 浏览: 21241 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

使用hibernate开发相册时,相册与照片的一对多问题!

阅读更多
大家好!

我在做一个相册,每个相册中可能有n张照片。目前相册与照片也配置成了双向一对多的关系。但我一直担心会出性能问题。
因为我发现好像用hibernate3的JPA配置里面,无法将一的一端设为“inverse”。所以如果添加相片,必须这样:
photo.setAlbum(album);
album.getPhotos().put(photo);
albumManager.save(album);
这样每添加一张照片,就要获取一遍该相册中的所有相片!
有没有更好的办法?
比如将相片和相册设置成单向多对一?
或者干脆不配置关联,直接用程序逻辑控制关联?(我以前都是这么做的,但现在发现ORM的精髓就是关联,不配置关联实在可惜)
或者用大缓存解决这种问题?(总感觉不太合适,而且我们现在没有钱购买很贵的机器,如果非要这样的话,我觉得hibernate在这一点设计的也太烂了吧?)

刚还看了下面这篇帖子,跟我问的问题差不多,但几乎没有人能给予一个很肯定并且很有说服的答复。
http://www.iteye.com/topic/59707?page=1

恳请各位热心的大侠给予答复,谢谢!


=====================================================================


该问题已经解决,发现原来双向一对多的关联关系下,关联的双方都可以作为关系的主控端。所以使用的时候可以灵活运用。该问题自然迎刃而解!

附上测试代码,在Junit下测试通过:

public void testAddAndRemoveAlbum2() throws Exception {
        Album album = new Album();
        //album = (Album) populate(album);
        album.setName("iiiiiiiii");
        album.setOwnerDisplayName("ssssssssss");
        album.setOwnerId(new Long(-10));

        Photo photo = new Photo();
        photo.setCover(Boolean.FALSE);
        photo.setOwnerId(new Long(8));
        photo.setPhotoPostfix(".jpg");
        photo.setTitle("xxxxxxxxxxxxxxxxxxxxxx");

        photo.setAlbum(album);
        album.getPhotos().add(photo);

        album = albumManager.addAlbum(album);
        assertNotNull(album.getId());
        assertEquals("iiiiiiiii",album.getName());
        assertEquals(1,album.getPhotos().size());

        photo = album.getPhotos().iterator().next();
        assertEquals(".jpg",photo.getPhotoPostfix());
        assertEquals("iiiiiiiii",photo.getAlbum().getName());
       
        long photoId = photo.getId();

        //Photo photo = photoManager.get(-2L);
        //album = albumManager.updateAlbum(album);

        log.debug("removing photo...");

        /**
         * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         * Hibernate之deleted object would be re-saved by cascade 异常的解决
         * 解决关联关系后,再删除 :
         *
         * 还有其他几种解决方案:
         * 1) 删除Set方的cascade——将Photo类中对album的cascade属性删掉。
         * 2)
         */
        album.removePhoto(photo);
        photo.setAlbum(null);
       
        albumManager.removePhoto(photoId);

        try {
            photo = albumManager.getPhoto(photoId);
            fail("Photo found in database");
        } catch (DataAccessException e) {
            log.debug("Expected exception: " + e.getMessage());
            assertNotNull(e);
        }
       
        album = albumManager.getAlbum(album.getId());
        assertNotNull(album);
        assertEquals(0,album.getPhotos().size());
       
    }  // end testAddAndRemoveAlbum2

   
   
    /**
     *
     * @throws Exception
     */
    public void testAddAndRemovePhoto() throws Exception {
        Album album = new Album();
        //album = (Album) populate(album);
        album.setName("iiiiiiiii");
        album.setOwnerDisplayName("ssssssssss");
        album.setOwnerId(new Long(-10));
        //album = albumManager.addAlbum(album);
       
        Photo photo = new Photo();
        photo.setCover(Boolean.FALSE);
        photo.setOwnerId(new Long(8));
        photo.setPhotoPostfix(".jpg");
        photo.setTitle("xxxxxxxxxxxxxxxxxxxxxx");

        photo.setAlbum(album);
        album.getPhotos().add(photo);  // 这句话必须设上,不然后面album的photos里面找不到。
       
        photo = albumManager.addPhoto(photo);
       
        assertNotNull(photo.getId());
        assertEquals("xxxxxxxxxxxxxxxxxxxxxx",photo.getTitle());
        assertEquals("iiiiiiiii",photo.getAlbum().getName());

        long albumId = photo.getAlbum().getId();
        album = this.albumManager.getAlbum(albumId);
        assertEquals(1,album.getPhotos().size());
       
        log.debug("removing photo...");
       
        long photoId = photo.getId();
       
        /**
         * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         * Hibernate之deleted object would be re-saved by cascade 异常的解决
         * 解决关联关系后,再删除 :
         *
         * 还有其他几种解决方案:
         * 1) 删除Set方的cascade——将Photo类中对album的cascade属性删掉。
         * 2)
         */
        album.removePhoto(photo);
        photo.setAlbum(null);
       
        albumManager.removePhoto(photoId);
       
        try {
            photo = albumManager.getPhoto(photoId);
            fail("Photo found in database");
        } catch (DataAccessException e) {
            log.debug("Expected exception: " + e.getMessage());
            assertNotNull(e);
        }
       
        /**
         *  function getAlbumPhotoCount{
         *      String hql = "select count(*) from Photo as ph where ph.album = ? ";
                List ul = getHibernateTemplate().find(hql,new Object[]{al});
         *  }
         * 如果不在前面删除album和photo的关联,当执行到这句话时,会报"deleted object would be re-saved by cascade"异常。
         * 调试发现,执行getAlbum(),album中的photos应是懒加载的,但仍然加载了,可以判断是因为一级缓存没有更新的缘故。
         */
        album = albumManager.getAlbum(albumId);
        assertNotNull(album);
        assertEquals(0,album.getPhotos().size());
       
    }  // end testAddAndRemovePhoto



分享到:
评论
3 楼 rustlingwind 2009-08-02  
herowzz 写道
photo.setAlbum(album);
photoManager.save(photo);


这个写法的前提是photo作为一对多关系的主控端吧!
但是我设置album和photo的双向一对多关系时,发现好像只能是由album作为主控端,查了很多资料也是这么写的。。。
而以前用多对多关系的时候,两边谁做主控端都可以的。
一对多却只能一的一端做主控端,所以很苦恼!

不知道上面的兄弟是如何做到让photo做一对多关系维护的主控端的。

p.s. 我的配置如下:

@Entity
@Table(name="alb_album")
public class Album implements Serializable {
    private Set<Photo> photos = new HashSet<Photo>();

    @OneToMany(cascade=CascadeType.ALL,mappedBy="album",fetch=FetchType.LAZY)
    public Set<Photo> getPhotos() {
        return photos;
    }
    public void setPhotos(Set<Photo> photos) {
        this.photos = photos;
    }

}

@Entity
@Table(name="alb_photo")
public class Photo implements Serializable{

    private Album album;

    @ManyToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH })
    @JoinColumn(name="album_id")
    public Album getAlbum() {
        return album;
    }

    public void setAlbum(Album album) {
        this.album = album;
    }

}
2 楼 herowzz 2009-08-02  
photo.setAlbum(album);
photoManager.save(photo);
1 楼 zrzdemon 2009-08-02  
假如数据量比较大的话 最好不做关联

相关推荐

    简易电子相册

    该系统的核心特点包括创建相册、编辑相册信息、上传照片以及对照片进行评论,这些功能都是通过SSH(Spring、Struts和Hibernate)框架实现的。SSH框架是Java Web开发中常用的一套开源框架组合,它能够帮助开发者高效...

    SSH个人相册项目

    SSH个人相册项目是一个非常适合初学者实践的编程项目,它主要使用了Struts、Spring和Hibernate这三种技术,也就是我们常说的SSH框架。这个框架组合在Java Web开发中非常常见,用于构建高效、灵活的企业级应用程序。...

    java电子相册管理系统

    Java电子相册管理系统是一款基于Java编程语言开发的软件,主要功能是管理和展示个人或集体的照片集。该系统适用于个人用户以及小型组织,提供了便捷的照片上传、分类、检索和分享功能,使得照片的管理变得更加有序和...

    基于ssh的电子相册系统

    此外,Spring还提供了事务管理功能,确保在用户进行多步骤操作(如上传照片并创建新相册)时,数据的一致性和完整性。 3. Hibernate:作为持久化框架,Hibernate简化了数据库操作,通过对象关系映射(ORM)技术,将...

    J2EE 电子相册 源代码

    3. **JDBC(Java Database Connectivity)**:J2EE电子相册需要存储用户信息、照片和相册数据,这通常通过JDBC来实现与数据库的连接和交互。开发者可能使用SQL语句来执行CRUD(Create, Read, Update, Delete)操作。...

    java项目源码在线相册系统.rar

    通过分析这个Java在线相册系统,我们可以学习到如何使用Java技术栈构建一个完整的Web应用,并了解到在实际开发中需要考虑的诸多方面,包括性能、安全、用户体验等多个维度。这个项目源码是一个宝贵的教育资源,有助...

    java毕业设计项目开发-网络相册源码及使用说明.zip

    本项目是一个基于Java技术的毕业设计,主要目的是提供一个网络相册的应用,让用户可以上传、存储、管理和分享自己的照片。这个项目涵盖了多个重要的Java技术知识点,对于学习和理解Java Web开发有着极大的帮助。 1....

    基于ssh框架的相册系统

    相册模块用于创建、编辑和删除相册,每个相册可以包含多张照片;照片模块则涉及照片的上传、预览、下载等功能。这些模块之间的交互通过SSH框架的控制层进行协调,保证了业务流程的清晰和可维护性。 5. **系统层次...

    j2ee做的电子相册网站

    在这个场景中,我们讨论的是一个使用J2EE技术构建的电子相册网站,它具备了基本的功能,如上传照片、浏览相册、管理个人相册等。 **J2EE架构** 1. **Web层**:通常由Servlets和JSP(JavaServer Pages)组成,负责...

    J2EE网络相册管理系统.doc

    【Hibernate】是一个对象关系映射(ORM)框架,它简化了数据库操作,将Java对象与数据库表之间的映射关系自动化,使得开发人员可以更专注于业务逻辑而不是数据库层面的细节。 【Spring】是一个全面的企业级应用开发...

    SSH电子相册系统毕业课程源码设计+论文+答辩ppt资料

    本系统主要是为了给那些对照片管理感兴趣的朋友提供一个交流的平台,对有很多照片需要管理的朋友,你在这里可以进行注册成为会员,上传自己的照片,也可以着浏览别人的相册,还可以修改个人资料。非注册会员你可以...

    java项目源码在线相册系统

    Java作为一种多平台、面向对象的语言,广泛应用于Web开发,尤其是后端服务。在线相册系统通常涉及到用户上传、存储、查看和分享照片的功能,它需要后端服务器处理这些请求,并与前端界面进行交互。 【描述】:...

    相片管理系统 可以用来管理相片,本系统使用了struts+hibernate

    为了满足这一需求,开发了一款名为"相片管理系统"的应用,它利用了Struts和Hibernate这两个强大的Java技术框架,实现了高效、便捷的照片存储、检索与管理功能。下面我们将深入探讨该系统的架构设计、核心技术和实际...

    电子相册系统的设计与实现.pdf

    通过上述知识点,我们可以了解到电子相册系统的复杂性和技术深度,从需求分析、系统设计到实现,涉及到的技术范围广泛,包括编程语言、Web开发、数据库管理、服务器部署等多个方面。系统的设计和实现不仅提高了用户...

    网络相册系统

    【网络相册系统】是一个基于Java Web技术的项目,它使用了JSP(JavaServer Pages)作为前端展示层,结合后端的SSH(Struts、Spring、Hibernate)框架,为用户提供了一个在线存储、管理和分享照片的平台。Oracle...

    WEB 在线相册小系统

    总的来说,【WEB在线相册小系统】涵盖了Web开发中的多个关键点:后端的Servlet和JSP处理、文件上传与下载、数据库操作、用户认证和权限管理、前端交互等。通过这个项目,初学者可以全面了解Web开发的基本流程,为...

    javaweb电子相册

    【JavaWeb电子相册】是一种基于JavaWeb技术开发的在线照片管理和分享应用。它允许用户上传、存储、浏览和管理个人或共享的照片集合,提供了一种便捷的方式在互联网上展示和分享生活瞬间。这个项目主要涉及到的技术栈...

    Java Web项目-讯友网络相册.zip

    综上所述,"Java Web项目-讯友网络相册"是一个综合性的开发案例,涵盖了Java Web开发中的诸多关键技术,对于学习和理解Java Web开发流程具有很高的参考价值。通过分析项目的源代码和文档,可以深入学习到上述各种...

    java源码:java项目源码在线相册系统.rar

    3. 照片上传:用户上传照片,可能使用多线程处理大文件,同时考虑图片格式转换和大小限制。 4. 权限控制:照片的查看权限可以设定为公开或私有,这需要在后端实现访问控制逻辑。 5. 照片浏览:用户可以按时间、标签...

    microblog_java_微博_相册_jsp_视频聊天_

    2. 相册管理与分享:用户可以上传照片,创建相册,并选择分享给其他用户。这需要处理图片的存储和显示,以及权限控制,确保用户对其内容的掌控。 总结,这个项目涵盖了Web开发的多个方面,包括后端架构设计、数据库...

Global site tag (gtag.js) - Google Analytics