Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Spring, Hibernate and lazy load, знаю - тема заезженная 
:(
    Опции темы
garbuz
Дата 7.5.2009, 00:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Здравствуйте. Вот для копаюсь со Spring и SpringMVC. Решил написать некое подобие блога. Итак.

Класс Post.java
Код

@Entity
@Table(name="posts")
public class Post {
    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="postId")
    private Long postId;
    
    @Column(name="title")
    private String postName;

    @Column(name="preview")
    private String preview;
    
    @Column(name="content")
    private String postBody;
    
    @ManyToOne(cascade = {CascadeType.REFRESH}, fetch = FetchType.EAGER)
    @JoinColumn(name="userId")
    private User author;
    
        
    @ManyToMany(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
    @JoinTable(name="posts_tags",
    joinColumns = @JoinColumn(name = "postId"),
    inverseJoinColumns = @JoinColumn(name = "tagId"))
    private Set<Tag> tags;
    
    @ManyToMany(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
    @JoinTable(name="posts_categories",
    joinColumns = @JoinColumn(name = "postId"),
    inverseJoinColumns = @JoinColumn(name = "categoryId"))
    private Set<Category> categories;
    
    
    @ManyToOne(cascade = {CascadeType.REFRESH}, fetch = FetchType.LAZY)
    @JoinColumn(name="statusId")
    private Status status;

    @Column(name="createdDate")
    private Date createdDate;

    @Column(name="modifiedDate")
    private Date modifiedDate;
    
    ...//getters and setters
}


Класс PostDAOImpl.java
Код

public class PostDAOImpl implements IPostDAO{

    private HibernateTemplate template;

    public void setTemplate(HibernateTemplate template) {
        this.template = template;
    }

    public void create(Post post) {
        System.out.println("PostDAOImpl => create");
        template.save(post);
        
    }

    public void delete(Post post) {
        System.out.println("PostDAOImpl => delete");
        template.delete(post);
        
    }

    public List<Post> getAll() {
        System.out.println("PostDAOImpl => getAll");
        return template.find("FROM Post order by createdDate");
    }

    public Post getById(Long postId) {
        System.out.println("PostDAOImpl => getById");
        return (Post) template.load(Post.class, postId);
    }

    public void update(Post post) {
        System.out.println("PostDAOImpl => update");
        template.saveOrUpdate(post);
    }


    public Post getByPostName(String postName) {
        return (Post)template.find("from Post p where p.postName = ?", postName).get(0);
    }

    public List<Post> getByUserName(String userName) {
        return template.find("from Post p, User u where p.author = u and u.login = ?", userName);
    }

   
}



Контроллер
Код

public class PostController extends AbstractController {

     private DAOFacade daoFacade;

    public void setDaoFacade(DAOFacade daoFacade) {
        this.daoFacade = daoFacade;
    }

    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse httpServletResponse) throws Exception {
        String postId = request.getParameter("postId");
        Post post = daoFacade.getPostDAO().getById(Long.parseLong(postId));
        List<Comment> comments = daoFacade.getCommentDAO().getFromPost(post);
        HashMap<String, Object> model = new HashMap<String, Object>();
        model.put("post", post);
        model.put("comments", comments);
        return new ModelAndView("post", model);
    }
}


В этой строке 
Код

Post post = daoFacade.getPostDAO().getById(Long.parseLong(postId));

бросается  org.hibernate.LazyInitializationException: could not initialize proxy - no Session. 
Т.е. происходит вызов template.load(ost.class, postId), когда пытаюсь выбрать все посты через template.find("FROM Post order by createdDate"), то все нормально.
Почему объект Post никак не получить через load()? Ладно бы я явно где-то обращался post.getTags(), тем более у полей класса Post, что собираюсь использовать стоит FetchType.EAGER.
PM MAIL   Вверх
_and
Дата 7.5.2009, 04:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-developer
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 6.8.2004
Где: Новокузнецк

Репутация: 1
Всего: 4



попробуй использовать в getById(Long postId) метод template.get()

PM MAIL ICQ Jabber   Вверх
pompei
Дата 7.5.2009, 06:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 7.9.2007

Репутация: нет
Всего: 6



Когда вы получили объект, есть недогруженные данные (lazy-load), и вы недогруженный объект возвращаете, потом спринг отрубает коннект к БД, и потом наверное идет сериализация объекта, т.е. обращение к его всем данным, механизм lazy-load это хватает и пытается догрузить остальные данные - обращается к БД, но конекта уже нет!!!

Чтобы избежать ошибку нужно загрузить все данные до дисконнекта, для этого есть специальный метод HibernateTemplate.initialize( Serializable object ) - он не рекурсивный. А если какие-то данные не нужны, то необходимо сделать их null до initialize.

ЗЫ. И вообще, подобные ошибки должны отлаживаться на уровне функциональных тестов.

Это сообщение отредактировал(а) pompei - 7.5.2009, 07:02
--------------------
А всё оказывается гораздо проще: пассивные наноструктуры - активные наноструктуры - системы наносистем - молекулярные наносистемы - сингулярность! По пять лет на каждый этап.
PM MAIL   Вверх
garbuz
Дата 7.5.2009, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Цитата(_and @  7.5.2009,  04:26 Найти цитируемый пост)
попробуй использовать в getById(Long postId) метод template.get()

ну вроде даже как помогло.

Цитата(pompei @  7.5.2009,  06:55 Найти цитируемый пост)
Когда вы получили объект, есть недогруженные данные (lazy-load), и вы недогруженный объект возвращаете, потом спринг отрубает коннект к БД, и потом наверное идет сериализация объекта, т.е. обращение к его всем данным, механизм lazy-load это хватает и пытается догрузить остальные данные - обращается к БД, но конекта уже нет!!!

Это понятно.



Цитата(pompei @  7.5.2009,  06:55 Найти цитируемый пост)

Чтобы избежать ошибку нужно загрузить все данные до дисконнекта, для этого есть специальный метод HibernateTemplate.initialize( Serializable object ) - он не рекурсивный. А если какие-то данные не нужны, то необходимо сделать их null до initialize.

Если делать типа такого, то возникает такое же исключение 
Код

public Post getById(Long postId) {
        System.out.println("PostDAOImpl => getById");
        Post post = (Post) template.load(Post.class, postId);
        template.initialize(post.getCategories());
        template.initialize(post.getTags());
        template.initialize(post.getAuthor());
        template.initialize(post.getStatus());
    return post;
        //return (Post) template.get(Post.class, postId);
    }

Как я понимаю, template сам после загрузки закрывает сессию и нам даже насильно уже ничего не проинициализировать.
PM MAIL   Вверх
powerOn
Дата 7.5.2009, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



Вот это еще посмотрите: Open Session in View. Разделяю мнение pompei, скорее всего идет обращение к данным, которые должны быть лениво загружены, когда сессия уже закрыта. 


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
_and
Дата 7.5.2009, 10:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-developer
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 6.8.2004
Где: Новокузнецк

Репутация: 1
Всего: 4



2powerOn, где-то читал про то что так не кошерно делать сцылку че-то найти не могу
PM MAIL ICQ Jabber   Вверх
garbuz
Дата 7.5.2009, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Цитата(powerOn @  7.5.2009,  10:34 Найти цитируемый пост)
Вот это еще посмотрите: Open Session in View. 

Спасибо, гляну.



Цитата(powerOn @  7.5.2009,  10:34 Найти цитируемый пост)
Разделяю мнение pompei, скорее всего идет обращение к данным, которые должны быть лениво загружены, когда сессия уже закрыта.  

Нет, эксепшн вылетает еще до обращения к каким-либо данным, делаю так:
Код

public Post getById(Long postId) {
        System.out.println("PostDAOImpl => getById");
         return (Post) template.load(Post.class, postId);
    }

У объекта Post все поля, которые связаны с другими таблицами стоит FetchType.EAGER. 
После выполнения этой строчки
Код

 Post post = daoFacade.getPostDAO().getById(Long.parseLong(postId));

Уже эксепшн в дебаггере наблюдаю и все поля null, даже те что никак не связаны с другими объектами.
PM MAIL   Вверх
garbuz
Дата 7.5.2009, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



При использовании вышеуказанного метода с использовнием load, выборки вообще не приосходит, вто что пишет хибернейт
Код

ostDAOImpl => getAll
Hibernate: select post0_.postId as postId2_, post0_.title as title2_, post0_.preview as preview2_, post0_.content as content2_, post0_.userId as userId2_, post0_.statusId as statusId2_, post0_.createdDate as createdD5_2_, post0_.modifiedDate as modified6_2_ from posts post0_ order by post0_.createdDate
Hibernate: select user0_.userId as userId4_0_, user0_.login as login4_0_, user0_.password as password4_0_, user0_.email as email4_0_, user0_.statusId as statusId4_0_ from users user0_ where user0_.userId=?
Hibernate: select tags0_.postId as postId1_, tags0_.tagId as tagId1_, tag1_.tagId as tagId3_0_, tag1_.tagName as tagName3_0_, tag1_.weight as weight3_0_ from posts_tags tags0_ left outer join tags tag1_ on tags0_.tagId=tag1_.tagId where tags0_.postId=?
PostDAOImpl => getById
CommentDAOImpl => getFromPost
Hibernate: select comment0_.commentId as commentId1_, comment0_.message as message1_, comment0_.userId as userId1_, comment0_.postId as postId1_, comment0_.statusId as statusId1_, comment0_.date as date1_ from comments comment0_ where comment0_.postId=?
Hibernate: select user0_.userId as userId4_0_, user0_.login as login4_0_, user0_.password as password4_0_, user0_.email as email4_0_, user0_.statusId as statusId4_0_ from users user0_ where user0_.userId=?
07.05.2009 14:57:32 org.hibernate.LazyInitializationException <init>
SEVERE: could not initialize proxy - no Session
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
    at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
    at ru.habrahabr.blog.entity.Post$$EnhancerByCGLIB$$af8a5d3b.getPostName(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at javax.el.BeanELResolver.getValue(BeanELResolver.java:62)
    at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:53)
    at org.apache.el.parser.AstValue.getValue(AstValue.java:118)
    at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
    at org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:925)
    at org.apache.jsp.post_jsp._jspx_meth_c_005fout_005f0(post_jsp.java:124)
    at org.apache.jsp.post_jsp._jspService(post_jsp.java:76)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:630)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
    at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:240)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:258)
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1174)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:901)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Thread.java:619)


Типа сперва выбираются все посты, когда загружается главная страница, потом когда щелкаю читать далее, должен выбраться конкретный пост, но он не выбирается, выбираются только комментарии.
PM MAIL   Вверх
Tony
Дата 7.5.2009, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1159
Регистрация: 3.3.2006
Где: Riga

Репутация: 6
Всего: 12



Иcпользуйте Hibernate.initialize();


--------------------
user posted image
user posted image
PM MAIL Skype   Вверх
garbuz
Дата 7.5.2009, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Цитата(Tony @  7.5.2009,  14:53 Найти цитируемый пост)
Иcпользуйте Hibernate.initialize(); 

Так а в каком месте использовать?
Код

public Post getById(Long postId) {
        System.out.println("PostDAOImpl => getById");
        Post post = (Post) template.load(Post.class, postId);
        template.initialize(post.getCategories());
        template.initialize(post.getTags());
        template.initialize(post.getAuthor());
        template.initialize(post.getStatus());
        return post;
}

Так не работает. Тот же ексепшн.
PM MAIL   Вверх
pompei
Дата 8.5.2009, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 7.9.2007

Репутация: нет
Всего: 6



Цитата(garbuz @ 7.5.2009,  10:32)
Если делать типа такого, то возникает такое же исключение 

Значит не всё загружено - остались ещё "ленивые" данные - смотри внимательней.

У меня очень много уверенности полагать что ошибка именно в этом - съел сабаку на этом (просто обожрался).

Попробуй сделать без initialize - по тупому обратись ко всем, всем, всем данным (придётся ставить if-ы - проверки на null), и ошибка должна исчесть, ну а потом постепенно меняй на initialize

Это сообщение отредактировал(а) pompei - 8.5.2009, 10:38
--------------------
А всё оказывается гораздо проще: пассивные наноструктуры - активные наноструктуры - системы наносистем - молекулярные наносистемы - сингулярность! По пять лет на каждый этап.
PM MAIL   Вверх
garbuz
Дата 8.5.2009, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Цитата(pompei @  8.5.2009,  10:32 Найти цитируемый пост)
Попробуй сделать без initialize - по тупому обратись ко всем, всем, всем данным (придётся ставить if-ы - проверки на null), и ошибка должна исчесть, ну а потом постепенно меняй на initialize

Делаю так.
вызываю из контроллера
Код

Post post = daoFacade.getPostDAO().getById(Long.parseLong(postId));


сам метод
Код

public Post getById(Long postId) {
    System.out.println("PostDAOImpl => getById");
        Post post = (Post) template.load(Post.class, postId);
        return post;
    }

далее в контроллере обращаюсь
Код

System.out.println("post");
        if (post.getPostId() == null) System.out.println("id is null");
        if (post.getPreview() == null) System.out.println("preview is null");
        if (post.getAuthor() == null) System.out.println("author is null");
        


при первом же обращении к обхекту post валится эксепшн. id - это же не ленивые данные?! Какой тогда нафиг эксепшн?

Самое интересное что, при вызове template.get Все работает. Смотрим доки хибернейта
Цитата

public Object get(Class clazz,
                  Serializable id)
           throws HibernateException

    Return the persistent instance of the given entity class with the given identifier, or null if there is no such persistent instance. (If the instance, or a proxy for the instance, is already associated with the session, return that instance or proxy.)

    Parameters:
        clazz - a persistent class
        id - an identifier 
    Returns:
        a persistent instance or null 
    Throws:
        HibernateException




Цитата

load

public Object load(Class theClass,
                   Serializable id)
            throws HibernateException

    Return the persistent instance of the given entity class with the given identifier, assuming that the instance exists.

    You should not use this method to determine if an instance exists (use get() instead). Use this only to retrieve an instance that you assume exists, where non-existence would be an actual error.

    Parameters:
        theClass - a persistent class
        id - a valid identifier of an existing persistent instance of the class 
    Returns:
        the persistent instance or proxy 
    Throws:
        HibernateException




Насколько я понял оба метода выполняют одно и то же действие - различие в том, что метод load надо использовать только тогда, когда ты уверен, что нужный объект существует, ну а я же знаю, что он существует.  smile 
PM MAIL   Вверх
pompei
Дата 12.5.2009, 06:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 7.9.2007

Репутация: нет
Всего: 6



Может просто объекта с таким идентификатором нету в БД?

Короче ошибка какая-то тупая и идиотская, но очень хорошо замаскированная!!! Попробуйте программу дать посмотреть другому программисту со свежим умом (и обязательно выспавшемуся), он скорей всего быстро найдёт.


Это сообщение отредактировал(а) pompei - 12.5.2009, 06:30
--------------------
А всё оказывается гораздо проще: пассивные наноструктуры - активные наноструктуры - системы наносистем - молекулярные наносистемы - сингулярность! По пять лет на каждый этап.
PM MAIL   Вверх
Старовъръ
Дата 12.5.2009, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.5.2008

Репутация: 1
Всего: 10



Про варианты борьбы с ленивой загрузкой можно здесь почить.
Попробовал пользовать load() - валятся все тесты))

Это сообщение отредактировал(а) Старовъръ - 12.5.2009, 12:35
PM MAIL WWW   Вверх
_and
Дата 12.5.2009, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-developer
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 6.8.2004
Где: Новокузнецк

Репутация: 1
Всего: 4



Цитата(Старовъръ @  12.5.2009,  16:33 Найти цитируемый пост)
Попробовал пользовать load() - валятся все тесты))

а чем метод get не нравится он же работает

PM MAIL ICQ Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0651 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.