JPA 1 @ встроен в метод доступа, возвращающий тип интерфейса - PullRequest
2 голосов
/ 24 ноября 2010

Я хочу использовать @Embedded для метода доступа, который возвращает тип интерфейса, а не фактический impl, но, похоже, JPA этого не поддерживает.

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

Пример

interface IEmail{  
    String getLocalPart();  
    String getDomainPart();   
    String getEmailAddress();  
}

class Email implements IEmail{
    @Transient
    String getLocalPart(){}
    @Transient
    String getDomainPart(){}  
    @Column(..) 
    String getEmailAddress(){}
}

interface IUser{
   IEmail getEmail();
}

class User implements IUser{   
    @Embedded 
    IEmail getEmail(){}
}

Я бы не хотел использовать абстрактные классы, так как интерфейсы находятся в отдельном проекте (который не зависит от jar-файла JPA), а impl находятся в отдельном проекте, поэтому, если я определяю Email как абстрактный класс в проекте интерфейса, я не могу использовать JPA аннотации.

Пожалуйста, помогите.

p.s. а. я не использую Hibernate Impl, поэтому не могу использовать @Target для решения этой проблемы б. Я использую это в платформе AppEngine с. Я еще не пробовал это в своем приложении, но я знаю, что он не будет работать, так как раньше я получил ошибку при работе с Hibernate и решил ее с помощью аннотации @Target


@ becomputer06 Спасибо за подробный ответ. К сожалению, AppEngine поддерживает только JPA 1.0 (см. здесь )

Так что я боюсь, что не могу использовать аннотацию @Access.

@ Bozho, как уже упоминалось, я просто хочу встроить класс в другой, но с указанием типов интерфейса. Пожалуйста, спросите больше, если это необходимо.

@ Datanucleus да, я видел ваши комментарии в других постах. я понимаю, но по каким-то причинам мы обосновались в JPA (по крайней мере, мы немного знакомы с этим - раньше мы работали над JPA + Hibernate)

Есть другие указатели? Еще раз спасибо

Ответы [ 2 ]

1 голос
/ 02 апреля 2012

Похоже, что это отвечает на некоторые вопросы, однако ваш пример полностью противоречит цели интерфейса IEMail, требуя известного impl.

if(email instanceof Email) {
    this.email = (Email) email;
} else {
    throw new IllegalArgumentException("not a valid type");
 }

Hibernate может сделать это с помощью сопоставлений компонентов и составного идентификатора

<composite-id name="id" class="org.adligo.models.core.client.ids.LongIdentifierMutant">
              <key-property name="id" column="tid"/>
        </composite-id>
        <component name="item_id" class="org.adligo.models.core.client.ids.LongIdentifierMutant" >
                <property name="id" column="item_id"/>
        </component>

Как это сделать в JPA?

1 голос
/ 24 ноября 2010

Я бы не хотел использовать абстрактные классы, так как интерфейсы находятся в отдельном проекте (который не зависит от jar-файла JPA), а impl находятся в отдельном проекте, поэтому, если я определю Email как абстрактный класс в проекте интерфейса, я могуне используйте аннотации JPA.

  • Если вы аннотируете метод получения с помощью @Embeddable И класс с помощью @Access(value=AccessType.PROPERTY), убедитесь, что вы аннотировали соответствующее поле с помощью @Access(value=AccessType.FIELD)переопределить свой AccessType по умолчанию (который совпадает с AccessType класса).

  • Если метод получателя возвращает тип интерфейса, а класс помечается @Access(value=AccessType.FIELD), то аннотируйте соответствующее поле с помощью@Embeddable (по умолчанию тип доступа к этому полю совпадает с типом доступа класса).

IEmail

public interface IEmail {
    String getEmailAddress();
    void setEmailAddress(String emailAddress);
}

Электронная почта

@Embeddable
public class Email implements IEmail, Serializable {
    private String emailAddress;

    public String getEmailAddress() {
        return emailAddress;
    }
    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }
}

IUser

public interface IUser {
    String getId();
    String getUserName();
    IEmail getEmail();
}

Пользователь аннотирован @Access (значение = AccessType.PROPERTY)

@Entity
@Access(value=AccessType.PROPERTY)
public class User implements IUser {

    private String id;
    private String userName;

    @Access(value=AccessType.FIELD)
    private Email email;

    @Id
@GeneratedValue 
    public long getId() { return id; }
    public void setId(long id) { this.id = id; }
    public String getUserName() { return userName; }
    public void setUserName(String userName) { this.userName = userName; }

    @Embedded
    public IEmail getEmail() {
        return email;
    }
    public void setEmail(IEmail email) {
        if(email instanceof Email) {
            this.email = (Email) email;
        } else {
            throw new IllegalArgumentException("not a valid type");
        }
    }

}

Пользователь аннотируется с помощью @Access (значение = AccessType.FIELD)

@Entity
@Access(value=AccessType.FIELD)
public class User {

    @Id
    @GeneratedValue() 
    private long id;

    private String userName;

    @Embedded
    private Email email;

    public long getId() { return id; }
    public void setId(long id) { this.id = id; }
    public String getUserName() { return userName; }
    public void setUserName(String userName) { this.userName = userName; }

    public IEmail getEmail() {
        return email;
    }
    public void setEmail(IEmail email) {
        if(email instanceof Email) {
            this.email = (Email) email;
        } else {
            throw new IllegalArgumentException("not a valid type");
        }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...