EclipseLink entity mapping problem when using prop

2019-08-02 15:47发布

Given the class below does anyone know why EclipseLink implementation of JPA fails to map them to database entities? The following error is returned:

Entity class [class com.my.entity.Y] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy.

@Entity
@Access(AccessType.PROPERTY)
public interface Y {

    void setId(Long id);

    @Id
    Long getId();
}

@Entity
public class Z implements Y {

    long id;

    @Override
    public void setId(Long id) {
        this.id = id;
    }

    @Override
    public Long getId() {
        return id;
    }
}

Many thanks

3条回答
霸刀☆藐视天下
2楼-- · 2019-08-02 16:03

Thanks to the person who linked to this question - it helped me come up with a solution to the issue as follows:

    @Entity
    public interface Y {

        void setId(Long id);

        @Id
        Long getId();
    }

   // introduce intermediate abstract class which implements Y

    @Entity
    public abstract class X implements Y {

    }

    // make Z extends X

    @Entity
    public class Z  extends X {

        // use targetEntity = X.class where required
        // leaving this class still free to use interface Y

        long id;

        @Override
        public void setId(Long id) {
            this.id = id;
        }

        @Override
        public Long getId() {
            return id;
        }
    }
查看更多
闹够了就滚
3楼-- · 2019-08-02 16:10

You cannot annotate or query on an inferface. You can only query @Entity classes, and these can only be placed on real classes, not interfaces. Use the @MappedSuperclass annotation for inheritance.

See these: http://download.oracle.com/javaee/6/tutorial/doc/bnbqn.html#bnbqp and JPA doesn't support interfaces well..implications?

查看更多
Summer. ? 凉城
4楼-- · 2019-08-02 16:14

EclipseLink does support querying and relationships to interfaces, but not currently in annotations.

To map the interface you can use a SessionCustomizer.

public class MyCustomizer implements SessionCustomizer {
    public void customize(Session session) {
      RelationalDescriptor descriptor = new RelationalDescriptor();
      descriptor.setJavaInterface(Y.class);
      descriptor.setAlias("Y");
      session.addDescriptor(descriptor);
    }
}

Mapping the interface allows querying on the interface which returns any of its subclasses, and defining relationships to the interface.

If the interface is used through the @VariableOneToOne annotation it will be automatically mapped.

查看更多
登录 后发表回答